Learn Immer and Interact with React Quickly
Are you familiar with immer.js? It's a nifty JavaScript library that makes working with immutable state a breeze. It provides a straightforward and easy-to-use API that acts like a helpful guide when you want to modify objects without actually changing them.
In simpler terms, think of it as a friendly assistant that lets you make updates to your data without the hassle of creating entirely new objects every time. Immer simplifies the process of managing state in a way that's both intuitive and concise. Let's dive into how it achieves this in a more user-friendly manner!
Let's start by exploring a fundamental use case of this library. Consider the following example to understand the basic usage of Immer:
import produce from 'immer';
// Initial state
const baseState = { count: 0 };
// Applying an update using Immer
const newState = produce(baseState, (draft) => {
draft.count += 1;
draft.value = "Updated";
});
In this basic example, produce
takes the baseState
and an update function named recipe
as arguments. The update function, operating on a draft of the state, makes modifications in a seemingly mutable manner.
Immer then efficiently generates a new immutable state (newState
), reflecting the applied changes.
In the provided code snippet, the newState
object is expected to have the following structure:
newState = {
count: 1,
value: 'Updated'
};
Alright, let's delve a bit deeper into the magic of immer.js.
We've seen how it's like a helpful buddy for changing stuff without really changing it. Now, imagine this buddy can be a bit more versatile, like having a superpower of applying the same kind of change to different things.
That's where the cool concept of "currying" comes in with Immer! Let's check it out in a way that's easy to understand.
import produce from 'immer';
// Imagine you have this curried buddy
const curriedUpdate = produce((draftState) => {
draftState.count += 1;
});
// And you can use it like this with different states
const state1 = { count: 0 };
const updatedState1 = curriedUpdate(state1);
const state2 = { count: 5 };
const updatedState2 = curriedUpdate(state2);
So, this curried buddy, curriedUpdate
, is like a recipe for making changes. You can use it with different state
ingredients, and it applies the same kind of magic to each one. It's like having a favorite spice blend for cooking that you sprinkle on various dishes to make them taste just right!
Now, let's explore how immer.js plays along with the set function returned by useState
in React.
import React, { useState } from 'react';
import produce from 'immer';
function MyComponent() {
// Setting up our state with useState
const [myState, setMyState] = useState({ count: 0, value: "Hello" });
// Creating our immer buddy for making updates
const updateState = produce((draftState) => {
draftState.count += 1;
draftState.value = "Updated!";
});
// When you want to update the state, just use setMyState with our immer buddy
const handleClick = () => {
setMyState(updateState);
};
return (
<div>
<p>Count: {myState.count}</p>
<p>Value: {myState.value}</p>
<button onClick={handleClick}>Click me!</button>
</div>
);
}
export default MyComponent;
Let's simplify it:
-
useState
delivers the basics: It gives us the current state (myState
) and a helper, thesetMyState
function, for making updates when needed. -
The immer buddy takes the stage: Here comes our immer buddy (
updateState
). Think of it like a chef with a recipe book, ready to cook up some state changes. Currently, it's in a curried state, just waiting for the right moment. -
Button click simplicity: When the button is clicked, we unveil the magic! We use
setMyState
, toss in our immer buddyupdateState
, and in a blink, React steps up to perform a smooth state update routine.
In essence, useState
establishes the foundation, while the immer library prepares the changes, and setMyState
orchestrates the entire performance when the button takes center stage.
This unfolds because, when React manages setMyState
, it seamlessly injects the current state (myState
) as the first argument, lending an elegantly effortless process to state updates.
If you're not familiar with how React handles functions that become arguments of set functions, you can refer to this page.