From the docs:
[init, the 3d argument] lets you extract the logic for calculating the initial state outside the reducer. This is also handy for resetting the state later in response to an action.
And the code:
function init(initialCount) {
return { count: initialCount };
}
function reducer(state, action) {
switch (action.type) {
case 'reset':
return init(action.payload);
}
}
function Counter({initialCount}) {
const [state, dispatch] = useReducer(reducer, initialCount, init);
}
Why would I do that over reusing a constant initialState
?
const initialState = {
count: 5,
};
function reducer(state, action) {
switch (action.type) {
case 'reset':
return initialState;
}
}
function Counter({initialCount}) {
const [state, dispatch] = useReducer(reducer, initialState);
}
Looks less verbose to me.
Advertisement
Answer
EDIT july 2020: React documentation has now better explainations on this arg called lazy initializer
. Using this function in another way could result to breaking changes due to undocumented effect. Following answer remain valid.
As far as I can experiment, the init
function as third arg is a transformer of the initialState
.
It means that initialState
will not be used a initial state, but as arg for init
function. The return of this one will be the true initialState
. It could be usefull to avoid huge param during the useReducer
initialization line.
/* Here is the magic. The `initialState` pass to
* `useReducer` as second argument will be hook
* here to init the real `initialState` as return
* of this function
*/
const countInitializer = initialState => {
return {
count: initialState,
otherProp: 0
};
};
const countReducer = state => state; // Dummy reducer
const App = () => {
const [countState /*, countDispatch */] =
React.useReducer(countReducer, 2, countInitializer);
// Note the `countState` will be initialized state direct on first render
return JSON.stringify(countState, null, 2);
}
ReactDOM.render(<App />, document.body);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.4/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js"></script>