Skip to content

Commit

Permalink
Merge pull request #8800 from marmelab/Fix-FilterForm-infinite-loop
Browse files Browse the repository at this point in the history
Fix FilterForm infinite loop when used in a ReferenceManyField
  • Loading branch information
djhi authored Apr 4, 2023
2 parents 2e81138 + 236b77a commit 40f288b
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 13 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import get from 'lodash/get';
import { useCallback, useEffect, useRef } from 'react';
import get from 'lodash/get';
import isEqual from 'lodash/isEqual';

import { useSafeSetState, removeEmpty } from '../../util';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ import { TextField } from '../field';
import { ReferenceManyField } from './ReferenceManyField';
import { Datagrid } from '../list/datagrid/Datagrid';
import { Notification } from '../layout/Notification';
import { FilterForm } from '../list';
import { TextInput } from '../input';

export default { title: 'ra-ui-materialui/fields/ReferenceManyField' };

Expand All @@ -26,7 +28,15 @@ let books = [

const defaultDataProvider = {
getManyReference: (resource, params) => {
const result = books.filter(book => book.author_id === params.id);
const result = books
.filter(book => book.author_id === params.id)
.filter(book =>
params?.filter?.q
? book.title
.toLowerCase()
.includes(params.filter.q.toLowerCase())
: true
);
return Promise.resolve({
data: result,
total: result.length,
Expand Down Expand Up @@ -67,3 +77,16 @@ export const Basic = () => (
</ReferenceManyField>
</Wrapper>
);

export const WithFilter = () => (
<Wrapper>
<ReferenceManyField reference="books" target="author_id">
<FilterForm
filters={[<TextInput source="q" label="Search" alwaysOn />]}
/>
<Datagrid bulkActionButtons={false}>
<TextField source="title" />
</Datagrid>
</ReferenceManyField>
</Wrapper>
);
25 changes: 14 additions & 11 deletions packages/ra-ui-materialui/src/list/filter/FilterForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,11 @@ import {
useForm,
useFormContext,
} from 'react-hook-form';
import lodashSet from 'lodash/set';
import lodashUnset from 'lodash/unset';
import lodashGet from 'lodash/get';
import set from 'lodash/set';
import unset from 'lodash/unset';
import get from 'lodash/get';
import cloneDeep from 'lodash/cloneDeep';
import isEqual from 'lodash/isEqual';

import { FilterFormInput } from './FilterFormInput';
import { FilterContext } from '../FilterContext';
Expand All @@ -48,7 +49,9 @@ export const FilterForm = (props: FilterFormProps) => {
// Reapply filterValues when the URL changes or a user removes a filter
useEffect(() => {
const newValues = getFilterFormValues(form.getValues(), filterValues);
form.reset(newValues);
if (!isEqual(newValues, form.getValues())) {
form.reset(newValues);
}
}, [filterValues, form]);

useEffect(() => {
Expand All @@ -58,9 +61,9 @@ export const FilterForm = (props: FilterFormProps) => {
const isFormValid = await form.trigger();

if (isFormValid) {
if (lodashGet(values, name) === '') {
if (get(values, name) === '') {
const newValues = cloneDeep(values);
lodashUnset(newValues, name);
unset(newValues, name);
setFilters(newValues, displayedFilters);
} else {
setFilters(values, displayedFilters);
Expand Down Expand Up @@ -104,7 +107,7 @@ export const FilterFormBase = (props: FilterFormBaseProps) => {
const getShownFilters = () => {
const values = form.getValues();
return filters.filter((filterElement: JSX.Element) => {
const filterValue = lodashGet(values, filterElement.props.source);
const filterValue = get(values, filterElement.props.source);
return (
filterElement.props.alwaysOn ||
displayedFilters[filterElement.props.source] ||
Expand Down Expand Up @@ -185,7 +188,7 @@ export const mergeInitialValuesWithDefaultValues = (
)
.reduce(
(acc, filterElement: JSX.Element) =>
lodashSet(
set(
{ ...acc },
filterElement.props.source,
filterElement.props.defaultValue
Expand Down Expand Up @@ -250,10 +253,10 @@ const getInputValue = (
return '';
}
if (Array.isArray(formValues[key])) {
return lodashGet(filterValues, key, '');
return get(filterValues, key, '');
}
if (formValues[key] instanceof Date) {
return lodashGet(filterValues, key, '');
return get(filterValues, key, '');
}
if (typeof formValues[key] === 'object') {
const inputValues = Object.keys(formValues[key]).reduce(
Expand All @@ -274,5 +277,5 @@ const getInputValue = (
if (!Object.keys(inputValues).length) return '';
return inputValues;
}
return lodashGet(filterValues, key, '');
return get(filterValues, key, '');
};

0 comments on commit 40f288b

Please sign in to comment.