GitHub - immerjs/use-immer: Use immer to drive state with a React hooks (original) (raw)
use-immer
A hook to use immer as a React hook to manipulate state.
Installation
npm install immer use-immer
API
useImmer
useImmer(initialState)
is very similar to useState. The function returns a tuple, the first value of the tuple is the current state, the second is the updater function, which accepts an immer producer function or a value as argument.
Managing state with immer producer function
When passing a function to the updater, the draft
argument can be mutated freely, until the producer ends and the changes will be made immutable and become the next state.
Example: https://codesandbox.io/s/l97yrzw8ol
import React from "react"; import { useImmer } from "use-immer";
function App() { const [person, updatePerson] = useImmer({ name: "Michel", age: 33 });
function updateName(name) { updatePerson(draft => { draft.name = name; }); }
function becomeOlder() { updatePerson(draft => { draft.age++; }); }
return (
Hello {person.name} ({person.age})
<input onChange={e => { updateName(e.target.value); }} value={person.name} />Older
(obviously, immer is a little overkill for this example)
Managing state as simple useState hook
When passing a value to the updater instead of a function, useImmer
hook behaves the same as useState hook and updates the state with that value.
import React from 'react'; import { useImmer } from 'use-immer';
function BirthDayCelebrator(){ const [age, setAge] = useImmer(20);
function birthDay(event){
setAge(age + 1);
alert(Happy birthday #${age} Anon! hope you good
);
}
return(
Obviously if you have to deal with immutability it is better option passing a function to the updater instead of a direct value.
useImmerReducer
Immer powered reducer, based on useReducer hook
Example: https://codesandbox.io/s/2zor1monvp
import React from "react"; import { useImmerReducer } from "use-immer";
const initialState = { count: 0 };
function reducer(draft, action) { switch (action.type) { case "reset": return initialState; case "increment": return void draft.count++; case "decrement": return void draft.count--; } }
function Counter() { const [state, dispatch] = useImmerReducer(reducer, initialState); return ( <> Count: {state.count} <button onClick={() => dispatch({ type: "reset" })}>Reset <button onClick={() => dispatch({ type: "increment" })}>+ <button onClick={() => dispatch({ type: "decrement" })}>- </> ); }