function useEnhancedReducer(reducer, props, createInitialState, isStateEqual) {
  const prevStateRef = useRef()
  const actionRef = useRef()
  const enhancedReducer = useCallback(
    (state, action) => {
      actionRef.current = action
      state = getState(state, action.props)

      const changes = reducer(state, action)
      const newState = action.props.stateReducer(state, {...action, changes})

      return newState
    },
    [reducer],
  )
  const [state, dispatch] = useReducer(
    enhancedReducer,
    props,
    createInitialState,
  )
  const propsRef = useLatestRef(props)
  const dispatchWithProps = useCallback(
    action => dispatch({props: propsRef.current, ...action}),
    [propsRef],
  )
  const action = actionRef.current

  useEffect(() => {
    const prevState = getState(prevStateRef.current, action?.props)
    const shouldCallOnChangeProps =
      action && prevStateRef.current && !isStateEqual(prevState, state)

    if (shouldCallOnChangeProps) {
      callOnChangeProps(action, prevState, state)
    }

    prevStateRef.current = state
  }, [state, action, isStateEqual])

  return [state, dispatchWithProps]
}
Computes the controlled state using a the previous state, props,
two reducers, one from downshift and an optional one from the user.
Also calls the onChange handlers for state values that have changed.

@param {Function} reducer Reducer function from downshift.
@param {Object} props The hook props, also passed to createInitialState.
@param {Function} createInitialState Function that returns the initial state.
@param {Function} isStateEqual Function that checks if a previous state is equal to the next.
@returns {Array} An array with the state and an action dispatcher.