Skip to content

Commit

Permalink
use useGetMany in useReferencearrayfieldcontroller instead of crudGet…
Browse files Browse the repository at this point in the history
…ManyAccumulate

Closes #3552
  • Loading branch information
fzaninotto committed Aug 21, 2019
1 parent 204282a commit bbe62f9
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 37 deletions.
Original file line number Diff line number Diff line change
@@ -1,23 +1,25 @@
import { useEffect } from 'react';
import { useDispatch, useSelector, shallowEqual } from 'react-redux';
import { useMemo } from 'react';
import get from 'lodash/get';

import { crudGetManyAccumulate } from '../../actions';
import { getReferencesByIds } from '../../reducer/admin/references/oneToMany';
import { ReduxState, Record, RecordMap, Identifier } from '../../types';
import { Record, RecordMap, Identifier } from '../../types';
import { useGetMany } from '../../dataProvider';

/**
* @typedef ReferenceArrayProps
* @type {Object}
* @property {boolean} loaded: boolean indicating if the reference has already beeen loaded
* @property {Array} ids: the list of ids.
* @property {Object} data: Object holding the reference data by their ids
* @property {Array} ids the list of ids.
* @property {Object} data Object holding the reference data by their ids
* @property {Object} error the error returned by the dataProvider
* @property {boolean} loading is the reference currently loading
* @property {boolean} loaded has the reference already been loaded
* @property {string} referenceBasePath basePath of the reference
*/
interface ReferenceArrayProps {
loaded: boolean;
ids: Identifier[];
data: RecordMap;
error?: any;
loading: boolean;
loaded: boolean;
referenceBasePath: string;
}

Expand All @@ -35,7 +37,7 @@ interface Option {
*
* @example
*
* const { loaded, data, ids, referenceBasePath, currentSort } = useReferenceArrayFieldController({
* const { ids, data, error, loaded, loading, referenceBasePath } = useReferenceArrayFieldController({
* basePath: 'resource';
* record: { referenceIds: ['id1', 'id2']};
* reference: 'reference';
Expand All @@ -61,34 +63,25 @@ const useReferenceArrayFieldController = ({
record,
source,
}: Option): ReferenceArrayProps => {
const dispatch = useDispatch();
const { data, ids } = useSelector(
getReferenceArray({ record, source, reference }),
shallowEqual
);
useEffect(() => {
dispatch(crudGetManyAccumulate(reference, ids));
}, [reference, ids, record.id]); // eslint-disable-line react-hooks/exhaustive-deps

const ids = get(record, source) || [];
const { data, error, loading, loaded } = useGetMany(reference, ids);
const referenceBasePath = basePath.replace(resource, reference); // FIXME obviously very weak

return {
// eslint-disable-next-line eqeqeq
loaded: data != undefined,
ids,
data,
data: useMemo(() => indexById(data), [data]),
error,
loaded,
loading,
referenceBasePath,
};
};

const getReferenceArray = ({ record, source, reference }) => (
state: ReduxState
) => {
const ids = get(record, source) || [];
return {
data: getReferencesByIds(state, reference, ids),
ids,
};
};
const indexById = (records: Record[]) =>
records
.filter(r => typeof r !== 'undefined')
.reduce((prev, current) => {
prev[current.id] = current;
return prev;
}, {});

export default useReferenceArrayFieldController;
12 changes: 12 additions & 0 deletions packages/ra-core/src/dataProvider/useGetMany.ts
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,16 @@ const callQueries = debounce(() => {
.filter(v => v != null); // remove null values
if (accumulatedIds.length === 0) {
// no need to call the data provider if all the ids are null
queries.forEach(({ ids, setState, onSuccess }) => {
setState({
data: emptyArray,
loading: false,
loaded: true,
});
if (onSuccess) {
onSuccess({ data: emptyArray });
}
});
return;
}
dataProvider(
Expand Down Expand Up @@ -188,4 +198,6 @@ const callQueries = debounce(() => {
});
});

const emptyArray = [];

export default useGetMany;
13 changes: 8 additions & 5 deletions packages/ra-ui-materialui/src/field/ReferenceArrayField.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { Children, cloneElement } from 'react';
import React, { Children, cloneElement, memo } from 'react';
import PropTypes from 'prop-types';
import LinearProgress from '@material-ui/core/LinearProgress';
import { makeStyles } from '@material-ui/core/styles';
Expand Down Expand Up @@ -45,11 +45,12 @@ export const ReferenceArrayField = ({ children, ...props }) => {
}

return (
<ReferenceArrayFieldView
<PureReferenceArrayFieldView
{...props}
{...useReferenceArrayFieldController(props)}
children={children}
/>
>
{children}
</PureReferenceArrayFieldView>
);
};

Expand Down Expand Up @@ -87,7 +88,7 @@ export const ReferenceArrayFieldView = ({
referenceBasePath,
}) => {
const classes = useStyles({ classes: classesOverride });
if (loaded === false) {
if (!loaded) {
return <LinearProgress className={classes.progress} />;
}

Expand All @@ -113,4 +114,6 @@ ReferenceArrayFieldView.propTypes = {
referenceBasePath: PropTypes.string,
};

const PureReferenceArrayFieldView = memo(ReferenceArrayFieldView);

export default ReferenceArrayField;

0 comments on commit bbe62f9

Please sign in to comment.