patternjavascriptModeratepending
Pattern: Immutable data structures for predictable state
Viewed 0 times
immutablespreadstructuredCloneimmerfrozenstate
Problem
Mutable state shared between components leads to unpredictable bugs. One part of the code modifies data that another part depends on.
Solution
Treat data as immutable — create new copies instead of modifying:
// JavaScript: Immutable update patterns
// Objects:
const updated = { ...user, name: 'New Name' };
const nested = { ...user, address: { ...user.address, city: 'NYC' } };
// Arrays:
const added = [...items, newItem];
const removed = items.filter(i => i.id !== idToRemove);
const updated = items.map(i => i.id === id ? { ...i, done: true } : i);
// With structuredClone for deep copy:
const deep = structuredClone(original);
// Immer for complex updates:
import { produce } from 'immer';
const next = produce(state, draft => {
draft.users[0].address.city = 'NYC'; // Mutate the draft!
draft.items.push(newItem);
});
// 'next' is a new immutable object, 'state' unchanged
// Python: frozen dataclasses
from dataclasses import dataclass, replace
@dataclass(frozen=True)
class Point:
x: float
y: float
p1 = Point(1, 2)
p2 = replace(p1, x=3) # New Point(3, 2), p1 unchanged
// Benefits:
// - No unexpected side effects
// - Easy undo/redo (keep previous versions)
// - Safe concurrent access (no locks needed)
// - Simple change detection (reference equality)
// JavaScript: Immutable update patterns
// Objects:
const updated = { ...user, name: 'New Name' };
const nested = { ...user, address: { ...user.address, city: 'NYC' } };
// Arrays:
const added = [...items, newItem];
const removed = items.filter(i => i.id !== idToRemove);
const updated = items.map(i => i.id === id ? { ...i, done: true } : i);
// With structuredClone for deep copy:
const deep = structuredClone(original);
// Immer for complex updates:
import { produce } from 'immer';
const next = produce(state, draft => {
draft.users[0].address.city = 'NYC'; // Mutate the draft!
draft.items.push(newItem);
});
// 'next' is a new immutable object, 'state' unchanged
// Python: frozen dataclasses
from dataclasses import dataclass, replace
@dataclass(frozen=True)
class Point:
x: float
y: float
p1 = Point(1, 2)
p2 = replace(p1, x=3) # New Point(3, 2), p1 unchanged
// Benefits:
// - No unexpected side effects
// - Easy undo/redo (keep previous versions)
// - Safe concurrent access (no locks needed)
// - Simple change detection (reference equality)
Why
Immutable data eliminates an entire category of bugs. If data can't change, you can't accidentally modify something another part of the code depends on.
Revisions (0)
No revisions yet.