Megha bagri
Megha bagri

Reputation: 74

useReducer not updating the initialState when used with useContext

I have a form, which has to be pre-populated with some value. These values come from context. I am using a reducer to handle the state of the form, so I set the initial state of the reducer from what I get from the context. Now what is happening is the context changes but the reducer state doesn't change.

const { selectedCurrency } =
        useContext<CurrenciesContextType>(CurrenciesContext);

const [state, dispatch]: [CurrencyReducerState, Dispatch<any>] = useReducer(
    currencyReducer as ReducerWithoutAction<CurrencyReducerState>,
    selectedCurrency,
    init
);

Ideally, whenever the selectedCurrency changes, it should set the initial values. But it doesn't happen. Any idea why?. I have wrapped the parent component inside the provider. Also every time the selectedCurrency changes, I see the selectedCurrency changing but the reducer state doesn't change. If the component is re-rendered then the reducer picks up the changes and initializes correctly. Is there a way to achieve this?

Upvotes: 2

Views: 1465

Answers (2)

Megha bagri
Megha bagri

Reputation: 74

I was able to achieve this behaviour by adding a updateState action in my reducer and wrapping this action inside useEffect with selectedCurrency as its dependency :

useEffect(() => {
    actions.updateState(selectedCurrency)
}, [selectedCurrency])

here is what the action looks like :

updateState: (updatedState): void => 
    dispatch({type: "update", payload: updatedState})

The init() function is executed only once when the useReducer is first called.

Similar question - Updating useReducer 'state' using useEffect

Upvotes: 1

Chris Farmer
Chris Farmer

Reputation: 25396

Without more example code, it's hard to tell, but maybe you're forgetting to wrap your code with the context provider? The code that needs to use the context (objects and/or callbacks) needs to be wrapped in the provider.

return (
  <div className="App">
    {/* CurrenciesProvider enables children to use the context info */ } 
    <CurrenciesProvider>
      <CurrencySelector />
      <CurrencyDisplay />
    </CurrenciesProvider>
  </div>
);

Here's a codesandbox... https://codesandbox.io/s/kind-noether-zr9dq

Upvotes: 0

Related Questions