diff --git a/packages/ra-ui-materialui/src/input/AutocompleteArrayInput.spec.tsx b/packages/ra-ui-materialui/src/input/AutocompleteArrayInput.spec.tsx index 5aeff234aad..43587f5bf2a 100644 --- a/packages/ra-ui-materialui/src/input/AutocompleteArrayInput.spec.tsx +++ b/packages/ra-ui-materialui/src/input/AutocompleteArrayInput.spec.tsx @@ -397,6 +397,43 @@ describe('', () => { formApi.change('tags', ['p']); await waitForDomChange(); expect(setFilter).toHaveBeenCalledTimes(3); + expect(setFilter).toHaveBeenCalledWith(''); + }); + + it('should reset filter only when needed, even if the value is an array of objects (fixes #4454)', async () => { + const setFilter = jest.fn(); + let formApi; + const { getByLabelText } = render( +
{ + formApi = form; + return ( + + value && value.map(v => ({ id: v })) + } + format={value => value && value.map(v => v.id)} + setFilter={setFilter} + /> + ); + }} + /> + ); + const input = getByLabelText('resources.posts.fields.tags'); + fireEvent.change(input, { target: { value: 'p' } }); + expect(setFilter).toHaveBeenCalledTimes(2); + expect(setFilter).toHaveBeenCalledWith('p'); + formApi.change('tags', ['p']); + await waitForDomChange(); + expect(setFilter).toHaveBeenCalledTimes(3); + expect(setFilter).toHaveBeenCalledWith(''); }); it('should allow customized rendering of suggesting item', () => { diff --git a/packages/ra-ui-materialui/src/input/AutocompleteArrayInput.tsx b/packages/ra-ui-materialui/src/input/AutocompleteArrayInput.tsx index 7f621b4ad9d..c126e68cb96 100644 --- a/packages/ra-ui-materialui/src/input/AutocompleteArrayInput.tsx +++ b/packages/ra-ui-materialui/src/input/AutocompleteArrayInput.tsx @@ -167,6 +167,8 @@ const AutocompleteArrayInput: FunctionComponent< ...rest, }); + const values = input.value || []; + const [filterValue, setFilterValue] = React.useState(''); const getSuggestionFromValue = useCallback( @@ -174,10 +176,10 @@ const AutocompleteArrayInput: FunctionComponent< [choices, optionValue] ); - const selectedItems = useMemo( - () => (input.value || []).map(getSuggestionFromValue), - [input.value, getSuggestionFromValue] - ); + const selectedItems = useMemo(() => values.map(getSuggestionFromValue), [ + ...values, + getSuggestionFromValue, + ]); const { getChoiceText, getChoiceValue, getSuggestions } = useSuggestions({ allowDuplicates, @@ -215,7 +217,7 @@ const AutocompleteArrayInput: FunctionComponent< // would have to first clear the input before seeing any other choices useEffect(() => { handleFilterChange(''); - }, [input.value, handleFilterChange]); + }, [...values, handleFilterChange]); const handleKeyDown = useCallback( (event: React.KeyboardEvent) => {