Reputation: 75
const initialState = {count: 0};
function reducer(state, action) {
switch (action.type) {
case 'increment':
return {count: state.count + 1};
case 'decrement':
return {count: state.count - 1};
default:
throw new Error();
}
}
function Counter() {
const [state, dispatch] = useReducer(reducer, initialState);
return (
<>
Count: {state.count}
<button onClick={() => dispatch({type: 'decrement'})}>-</button>
<button onClick={() => dispatch({type: 'increment'})}>+</button>
</>
);
This is taken directly from the React documentation. I want to be specific with this one line of code:
const [state, dispatch] = useReducer(reducer, initialState);
In the newly created variables, state and dispatch we are assigning reducer to dispatch and initialState
to state. This seems backward to me. Why would we declare our state first if useReducer
is assigning the value from the second parameter of the function (initialState
). I hope that I am clear about this question... I know it can be tricky to understand what I am asking. Basically, why isn't the code setup like this instead?
const [dispatch, state] = useReducer(reducer, initialState);
Or:
const [state, dispatch] = useReducer(initialState, reducer);
Upvotes: 0
Views: 119
Reputation: 1413
useReducer
returns an array whose first value is the state and the second value is the dispatch. You are de-structuring these values.
const someArray = () => ['value1','value2']
const [value1 , value2] = someArray()
console.log(value1)
console.log(value2)
As far as why the order is the way it is:
useState
returns an array as[state, setState]
useReducer
returns an array as[state , dispatch]
As you can see both are very similar
Furthermore: a common theme when calling a function is to pass in the main argument (reducer) as the first argument then its options (initialState). useReducer(reducer, initialState)
Updated Edit Extended Answer:
This is because you will always pass the main argument and may not pass its options
If useReducer required you to call it with useReducer(initialValues, reducer)
you wouldn't be able to call it without initalValues such as useReducer(reducer)
as useReducer would then think that reducer was your initalValues and that no reducer was passed in.
React Team could have instead chose to accept an object such as {initalValues, reducer}
and order would not matter but that is not the case
Upvotes: 2