From e5347578ba04ee14bc4372a76ab86bce91c0e566 Mon Sep 17 00:00:00 2001 From: Silviu Alexandru Avram Date: Thu, 9 Nov 2023 10:19:45 +0000 Subject: [PATCH] fix(hooks): use createInitialState in reducer (#1556) --- src/hooks/useCombobox/index.js | 3 +-- src/hooks/useCombobox/utils.js | 12 ++++++++---- src/hooks/useMultipleSelection/index.js | 2 +- src/hooks/useSelect/index.js | 3 +-- src/hooks/utils.js | 24 ++++++++++++++++-------- 5 files changed, 27 insertions(+), 17 deletions(-) diff --git a/src/hooks/useCombobox/index.js b/src/hooks/useCombobox/index.js index 45a68716..04bd6048 100644 --- a/src/hooks/useCombobox/index.js +++ b/src/hooks/useCombobox/index.js @@ -39,11 +39,10 @@ function useCombobox(userProps = {}) { itemToString, } = props // Initial state depending on controlled props. - const initialState = getInitialState(props) const [state, dispatch] = useControlledReducer( downshiftUseComboboxReducer, - initialState, props, + getInitialState, ) const {isOpen, highlightedIndex, selectedItem, inputValue} = state diff --git a/src/hooks/useCombobox/utils.js b/src/hooks/useCombobox/utils.js index c4d977cf..6f41c205 100644 --- a/src/hooks/useCombobox/utils.js +++ b/src/hooks/useCombobox/utils.js @@ -56,13 +56,17 @@ const propTypes = { * compute the rest of the state. * * @param {Function} reducer Reducer function from downshift. - * @param {Object} initialState Initial state of the hook. - * @param {Object} props The hook props. + * @param {Object} props The hook props, also passed to createInitialState. + * @param {Function} createInitialState Function that returns the initial state. * @returns {Array} An array with the state and an action dispatcher. */ -export function useControlledReducer(reducer, initialState, props) { +export function useControlledReducer(reducer, props, createInitialState) { const previousSelectedItemRef = useRef() - const [state, dispatch] = useEnhancedReducer(reducer, initialState, props) + const [state, dispatch] = useEnhancedReducer( + reducer, + props, + createInitialState, + ) // ToDo: if needed, make same approach as selectedItemChanged from Downshift. useEffect(() => { diff --git a/src/hooks/useMultipleSelection/index.js b/src/hooks/useMultipleSelection/index.js index 9caa6b8f..87b32002 100644 --- a/src/hooks/useMultipleSelection/index.js +++ b/src/hooks/useMultipleSelection/index.js @@ -38,8 +38,8 @@ function useMultipleSelection(userProps = {}) { // Reducer init. const [state, dispatch] = useControlledReducer( downshiftMultipleSelectionReducer, - getInitialState(props), props, + getInitialState, ) const {activeIndex, selectedItems} = state diff --git a/src/hooks/useSelect/index.js b/src/hooks/useSelect/index.js index 16c4f78f..506ec613 100644 --- a/src/hooks/useSelect/index.js +++ b/src/hooks/useSelect/index.js @@ -42,11 +42,10 @@ function useSelect(userProps = {}) { getA11yStatusMessage, } = props // Initial state depending on controlled props. - const initialState = getInitialState(props) const [state, dispatch] = useControlledReducer( downshiftSelectReducer, - initialState, props, + getInitialState, ) const {isOpen, highlightedIndex, selectedItem, inputValue} = state diff --git a/src/hooks/utils.js b/src/hooks/utils.js index f140e4e0..3c6165c9 100644 --- a/src/hooks/utils.js +++ b/src/hooks/utils.js @@ -187,11 +187,11 @@ function useLatestRef(val) { * Also calls the onChange handlers for state values that have changed. * * @param {Function} reducer Reducer function from downshift. - * @param {Object} initialState Initial state of the hook. - * @param {Object} props The hook props. + * @param {Object} props The hook props, also passed to createInitialState. + * @param {Function} createInitialState Function that returns the initial state. * @returns {Array} An array with the state and an action dispatcher. */ -function useEnhancedReducer(reducer, initialState, props) { +function useEnhancedReducer(reducer, props, createInitialState) { const prevStateRef = useRef() const actionRef = useRef() const enhancedReducer = useCallback( @@ -206,7 +206,11 @@ function useEnhancedReducer(reducer, initialState, props) { }, [reducer], ) - const [state, dispatch] = useReducer(enhancedReducer, initialState) + const [state, dispatch] = useReducer( + enhancedReducer, + props, + createInitialState, + ) const propsRef = useLatestRef(props) const dispatchWithProps = useCallback( action => dispatch({props: propsRef.current, ...action}), @@ -234,12 +238,16 @@ function useEnhancedReducer(reducer, initialState, props) { * returning the new state. * * @param {Function} reducer Reducer function from downshift. - * @param {Object} initialState Initial state of the hook. - * @param {Object} props The hook props. + * @param {Object} props The hook props, also passed to createInitialState. + * @param {Function} createInitialState Function that returns the initial state. * @returns {Array} An array with the state and an action dispatcher. */ -function useControlledReducer(reducer, initialState, props) { - const [state, dispatch] = useEnhancedReducer(reducer, initialState, props) +function useControlledReducer(reducer, props, createInitialState) { + const [state, dispatch] = useEnhancedReducer( + reducer, + props, + createInitialState, + ) return [getState(state, props), dispatch] }