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>