Skip to content

Commit

Permalink
Merge pull request #1449 from data-driven-forms/mui-searchable-async-…
Browse files Browse the repository at this point in the history
…select

Common select fixes
  • Loading branch information
rvsia authored Mar 21, 2024
2 parents 271e466 + 23a38f5 commit 90f2774
Show file tree
Hide file tree
Showing 3 changed files with 19 additions and 15 deletions.
2 changes: 1 addition & 1 deletion packages/common/src/select/select.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ const Select = ({
simpleValue = true,
isMulti,
pluckSingleValue = true,
options: propsOptions = [],
options: propsOptions,
loadOptions,
loadingMessage,
placeholder = 'Choose...',
Expand Down
11 changes: 4 additions & 7 deletions packages/common/src/use-select/reducer.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ export const init = ({ propsOptions, optionsTransformer }) => ({
...(optionsTransformer && { originalOptions: propsOptions }),
});

const reducer = (state, { type, payload, options = [], optionsTransformer }) => {
const reducer = (state, { type, payload, options = [], optionsTransformer, compareValues }) => {
switch (type) {
case 'updateOptions':
return {
Expand Down Expand Up @@ -42,14 +42,11 @@ const reducer = (state, { type, payload, options = [], optionsTransformer }) =>
options: optionsTransformer
? optionsTransformer([
...state.options,
...options.filter(({ value }) => !state.options.find((option) => payload.compareValues(option.value, value))),
...options.filter(({ value }) => !state.options.find((option) => compareValues(option.value, value))),
])
: [...state.options, ...options.filter(({ value }) => !state.options.find((option) => payload.compareValues(option.value, value)))],
: [...state.options, ...options.filter(({ value }) => !state.options.find((option) => compareValues(option.value, value)))],
...(optionsTransformer && {
originalOptions: [
...state.options,
...options.filter(({ value }) => !state.options.find((option) => payload.compareValues(option.value, value))),
],
originalOptions: [...state.options, ...options.filter(({ value }) => !state.options.find((option) => compareValues(option.value, value)))],
}),
};
default:
Expand Down
21 changes: 14 additions & 7 deletions packages/common/src/use-select/use-select.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { useEffect, useReducer } from 'react';
import { useEffect, useReducer, useState } from 'react';

import isEqual from 'lodash/isEqual';

Expand Down Expand Up @@ -58,7 +58,7 @@ const handleSelectChange = (option, simpleValue, isMulti, onChange, allOptions,
const useSelect = ({
loadOptions,
optionsTransformer,
options: propsOptions,
options: initialOptions = [],
noValueUpdates,
onChange,
value,
Expand All @@ -69,8 +69,15 @@ const useSelect = ({
simpleValue,
compareValues,
}) => {
const [state, originalDispatch] = useReducer(reducer, { optionsTransformer, propsOptions }, init);
const dispatch = (action) => originalDispatch({ ...action, optionsTransformer });
const [propsOptions, setPropsCache] = useState(initialOptions);
const [state, originalDispatch] = useReducer(reducer, { optionsTransformer, propsOptions: initialOptions }, init);
const dispatch = (action) => originalDispatch({ ...action, optionsTransformer, compareValues });

useEffect(() => {
if (!isEqual(initialOptions, propsOptions)) {
setPropsCache(initialOptions);
}
}, [initialOptions]);

const isMounted = useIsMounted();

Expand Down Expand Up @@ -114,7 +121,7 @@ const useSelect = ({
}, [loadOptionsStr, loadOptionsChangeCounter]);

useEffect(() => {
if (state.isInitialLoaded) {
if (!isEqual(state.options, propsOptions) && state.isInitialLoaded) {
if (!noValueUpdates && value && !propsOptions.map(({ value }) => value).includes(value)) {
onChange(undefined);
}
Expand All @@ -125,14 +132,14 @@ const useSelect = ({

const onInputChange = (inputValue) => {
if (inputValue && loadOptions && state.promises[inputValue] === undefined && isSearchable) {
dispatch({ type: 'setPromises', payload: { [inputValue]: true, compareValues } });
dispatch({ type: 'setPromises', payload: { [inputValue]: true } });

loadOptions(inputValue)
.then((options) => {
if (isMounted.current) {
dispatch({
type: 'setPromises',
payload: { [inputValue]: false, compareValues },
payload: { [inputValue]: false },
options,
});
}
Expand Down

0 comments on commit 90f2774

Please sign in to comment.