Created
January 20, 2020 21:04
-
-
Save subhog/6e00e88a7d40e8e7a8223b8e77228faf to your computer and use it in GitHub Desktop.
The simplest useImmer hook
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { useReducer } from "react"; | |
import produce from "immer"; | |
export default (initialState) => ( | |
/* | |
First, we need to apply the `useReducer` hook. | |
React reducer signature is `(state, action)`, where `state` is the current state | |
and `action` is the argument provided to the `set` method. | |
In our case, `action` is just the `producer` method we'll pass to immer. | |
The reducer should return the new state, which we get via immer's `produce` method. | |
const [state, dispatch] = useReducer((state, producer) => produce(state, producer), initialState); | |
Notice that the reducer method is trivial here, so this line can be simplified to: | |
const [state, dispatch] = useReducer(produce, initialState); | |
Now, we want to return an `useState`-like pair where the method accepts a producer | |
and dispatches it as a new action: | |
return [state, (producer) => dispatch(producer)]; | |
Notice that this again is trivially simplified to: | |
return [state, dispatch]; | |
Which is exactly what we got from the previous line. | |
Hence, we arrived at this somewhat cryptic one liner. | |
*/ | |
useReducer(produce, initialState) | |
); | |
/* | |
Usage example: | |
const [state, setState] = useImmer({}); | |
... | |
setState(state => { | |
state.changed = true; | |
}); | |
*/ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment