Skip to content

Commit 291f686

Browse files
authored
Merge pull request #1367 from data-driven-forms/fix-mui-select
Fix mui select
2 parents 6d7448e + 50e00b8 commit 291f686

File tree

3 files changed

+18
-4
lines changed

3 files changed

+18
-4
lines changed

packages/common/src/select/select.js

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/* eslint-disable react-hooks/exhaustive-deps */
2-
import React from 'react';
2+
import React, { useMemo } from 'react';
33

44
import PropTypes from 'prop-types';
55
import clsx from 'clsx';
@@ -47,6 +47,12 @@ const Select = ({
4747
});
4848

4949
const renderNoOptionsMessage = () => (Object.values(state.promises).some((value) => value) ? () => updatingMessage : () => noOptionsMessage);
50+
// When isMulti is true, the "getSelect" always creates new value array, we need to memoize it to not create new array instance
51+
// Memo is required to fix https://github.com/data-driven-forms/react-forms/issues/1366
52+
// Keeping prev values in ref and calling lodash.isEqual is not reliable as it ca return false positive beucase it only has true/false result.
53+
// If we have multiple updates during one reconciliation pahse the search input reset will trigger on initial key stroke
54+
// JSON.stringify is expensive but seems to be working better.
55+
const selectValueInternal = useMemo(() => selectValue, [JSON.stringify(selectValue)]);
5056

5157
if (state.isLoading) {
5258
return (
@@ -58,6 +64,9 @@ const Select = ({
5864
placeholder={loadingMessage}
5965
options={state.options}
6066
onChange={() => {}}
67+
onInputChange={onInputChange}
68+
value={selectValueInternal}
69+
isMulti={isMulti}
6170
{...loadingProps}
6271
noOptionsMessage={renderNoOptionsMessage()}
6372
{...(state.originalOptions && { originalOptions: state.originalOptions })}
@@ -75,7 +84,7 @@ const Select = ({
7584
options={state.options}
7685
classNamePrefix={classNamePrefix}
7786
isMulti={isMulti}
78-
value={selectValue}
87+
value={selectValueInternal}
7988
onChange={selectOnChange}
8089
onInputChange={onInputChange}
8190
isFetching={isFetching}

packages/common/src/tests/select/select.test.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -471,6 +471,8 @@ describe('Select test', () => {
471471
isSearchable: false,
472472
options: [],
473473
placeholder: undefined,
474+
isMulti: undefined,
475+
value: [],
474476
});
475477

476478
await act(async () => {

packages/mui-component-mapper/src/select/select.js

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import React from 'react';
1+
import React, { useMemo } from 'react';
22
import PropTypes from 'prop-types';
33

44
import FormFieldGrid from '../form-field-grid/form-field-grid';
@@ -81,7 +81,10 @@ const InternalSelect = ({
8181
...rest
8282
}) => {
8383
const invalid = validationError(meta, validateOnMount);
84-
const internalValue = parseInternalValue(value, isMulti);
84+
// When isMulti is true, the "parseInternalValue" always creates new value array, we need to memoize it to not create new array instance
85+
// Memo is required to fix https://github.com/data-driven-forms/react-forms/issues/1366
86+
const internalValue = useMemo(() => parseInternalValue(value, isMulti), [value, isMulti]);
87+
8588
return (
8689
<FormFieldGrid {...FormFieldGridProps}>
8790
<Autocomplete

0 commit comments

Comments
 (0)