Understanding Immer.js: Immutable Data Handling in JavaScript and React
Immer.js, created by the author of MobX, provides a lightweight immutable data library for JavaScript using ES6 proxies, offering simple APIs and seamless integration with React’s state management, while comparing its concepts, implementation details, and trade‑offs against Immutable.js and manual cloning techniques.
What is Immer.js?
Immer.js is an immutable data library written by the author of MobX. It won the 2019 JavaScript Open Source Award. Its core implementation leverages ES6 proxy to provide a minimal‑cost, small‑size, and cleverly designed immutable data structure for JavaScript.
What is Immutable Data?
Mutable data changes the original object when a reference is altered, as shown by a simple example where modifying objB.name also changes objA.name . Immutable data, originating from functional programming, never mutates an existing value; each change creates a new value, preserving previous states.
JavaScript does not have built‑in immutable structures, so third‑party libraries like Immer.js or Immutable.js are used.
Why Pursue Immutable Data?
Problems with Data Copying Deep copying can be costly, especially with nested objects, symbols, or circular references.
Importance in React Immutable data speeds up React’s diff algorithm because the reconciler only needs to compare object references to detect changes.
Common Implementation Methods
Deep Copy
Deep copying incurs performance overhead and must handle prototype chains, symbols, and circular references.
Immutable.js
Immutable.js, from Facebook, provides its own data structures and API. Operations always return new immutable values, but the library is larger (~63 KB) and requires conversion between native and immutable types.
Immer.js Basics
Core Concepts
currentState : the original state passed to produce .
draftState : a proxy of currentState where all mutations are recorded.
nextState : the final immutable state generated from draftState .
produce : a function that creates nextState from currentState and a recipe (mutation function).
producer : a curried version of produce that can be reused.
recipe : the function that mutates draftState .
API Overview
First usage pattern:
import produce from 'immer';
const baseState = [{ title: 'study javascript', status: true }, { title: 'study immer', status: false }];
const nextState = produce(baseState, draftState => {
draftState.push({ title: 'study react' });
draftState[1].status = true;
});
// baseState remains unchanged, nextState reflects the mutationsSecond (curried) usage pattern:
const producer = produce(draft => { draft.x = 2 });
const nextState = producer({ p: { x: 5 } });How Immer.js Works
The process consists of three main steps:
Creating a Proxy (draft) : createProxy generates a proxy for the base object, storing it in an ImmerScope . If the environment lacks proxy support, an ES5 fallback is used.
Intercepting Reads/Writes : Custom get and set traps lazily create nested proxies (getter) and record modifications (setter), marking the draft as changed and copying the base shallowly when needed.
Finalizing the Result : After the recipe runs, processResult calls finalize to recursively freeze unchanged parts, apply recorded changes, generate patches if requested, and return nextState .
Immer.js in React Projects
Using setState with Immer:
onClick = () => {
this.setState(prev => ({
user: { ...prev.user, age: prev.user.age + 1 }
}));
};
// With Immer
onClickImmer = () => {
this.setState(produce(draft => { draft.user.age += 1; }));
};Hook integration via use-immer :
import React from 'react';
import { useImmer } from 'use-immer';
const [person, updatePerson] = useImmer({ name: 'tom', age: 25 });
function updateName(name) {
updatePerson(draft => { draft.name = name; });
}Pros and Cons
Advantages : Native‑syntax API, low learning curve, tiny bundle (~4.3 KB), structural sharing, automatic freezing of unchanged parts.
Disadvantages : Requires proxy support; older browsers fall back to defineProperty , which can be roughly twice as slow.
References
Official documentation
Introducing Immer: Immutability the easy way
Copy‑on‑write articles
ByteDance ADFE Team
Official account of ByteDance Advertising Frontend Team
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.