Skip to content

Commit 566bd26

Browse files
committed
docs(readme): update
1 parent 8be25c4 commit 566bd26

File tree

1 file changed

+16
-3
lines changed

1 file changed

+16
-3
lines changed

README.md

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,8 @@ Update the state. Supports three styles:
153153
- **Function returning value:** `setState(() => ({ count: 1 }))` - Compute new state
154154
- **Draft mutation (recommended):** `setState((draft) => { draft.count = 1 })` - Mutate a draft copy
155155

156+
> **Performance Optimization:** Updates that produce no actual changes (empty patches) won't create history entries or trigger subscribers. For example, `setState(state => state)` or conditional updates that don't modify any fields. This prevents memory bloat from no-op operations.
157+
156158
#### `subscribe(listener: (state, patches, position) => void): () => void`
157159

158160
Subscribe to state changes. Returns an unsubscribe function.
@@ -309,6 +311,7 @@ Stick with the default immutable mode for reducer-driven stores (Redux, Zustand)
309311
### Behavior at a Glance
310312

311313
- `setState` keeps the reference stable as long as the current state root is an object. Primitive roots (number, string, `null`) trigger an automatic immutable fallback plus a dev warning.
314+
- No-op updates (producing empty patches) are optimized away and won't create history entries or notify subscribers.
312315
- `back`, `forward`, and `go` also mutate in place unless the history entry performs a root-level replacement (patch path `[]`). Those rare steps reassign the reference to keep history correct.
313316
- `reset` replays a diff from the original initial state, so the observable reference survives a reset.
314317
- `archive` (manual mode) merges temporary patches and still mutates the live object before saving history.
@@ -425,9 +428,19 @@ const travels = createTravels({ count: 0 });
425428
// or explicitly: createTravels({ count: 0 }, { autoArchive: true })
426429

427430
// Each setState creates a new history entry
428-
travels.setState({ count: 1 }); // History: [0, 1]
429-
travels.setState({ count: 2 }); // History: [0, 1, 2]
430-
travels.setState({ count: 3 }); // History: [0, 1, 2, 3]
431+
travels.setState({ count: 1 }); // History: [0, 1], position: 1
432+
travels.setState({ count: 2 }); // History: [0, 1, 2], position: 2
433+
travels.setState({ count: 3 }); // History: [0, 1, 2, 3], position: 3
434+
435+
// No-op update - position stays the same (optimization)
436+
travels.setState(state => state); // History: [0, 1, 2, 3], position: 3
437+
438+
// Conditional update that changes nothing
439+
travels.setState(draft => {
440+
if (draft.count > 10) { // false, so no changes
441+
draft.count = 0;
442+
}
443+
}); // History: [0, 1, 2, 3], position: 3
431444

432445
travels.back(); // Go back to count: 2
433446
```

0 commit comments

Comments
 (0)