Skip to content

Commit b036844

Browse files
committed
docs(website): update docs
1 parent 65858df commit b036844

File tree

3 files changed

+68
-0
lines changed

3 files changed

+68
-0
lines changed

README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -610,6 +610,10 @@ Yes. Unless you have to be compatible with Internet Explorer, Mutative supports
610610

611611
Yes. Mutative supports return values for reducer, and `redux-toolkit` is considering support for [configurable `produce()`](https://github.com/reduxjs/redux-toolkit/pull/3074).
612612

613+
- Does Mutative support shared references?
614+
615+
Yes, Mutative supports shared references, but **each path to a shared object gets its own independent draft**. Modifications to one path do not automatically reflect in others. If you want to preserve shared references in the result, you must explicitly assign them (e.g., `draft.b = draft.a`). [Read more details](https://mutative.js.org/docs/extra-topics/shared-references).
616+
613617
## Migration from Immer to Mutative
614618

615619
> [mutative-compat](https://github.com/exuanbo/mutative-compat) - Mutative wrapper with full Immer API compatibility, you can use it to quickly migrate from Immer to Mutative.

website/docs/extra-topics/faq.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,3 +21,7 @@ Yes. Unless you have to be compatible with Internet Explorer, Mutative supports
2121
- Can Mutative be integrated with Redux?
2222

2323
Yes. Mutative supports return values for reducer, and `redux-toolkit` is considering support for [configurable `produce()`](https://github.com/reduxjs/redux-toolkit/pull/3074).
24+
25+
- Does Mutative support shared references?
26+
27+
Yes, Mutative supports shared references, but **each path to a shared object gets its own independent draft**. Modifications to one path do not automatically reflect in others. If you want to preserve shared references in the result, you must explicitly assign them (e.g., `draft.b = draft.a`). [Read more details](./shared-references.md).
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
---
2+
sidebar_position: 4
3+
title: Shared References
4+
---
5+
6+
# Shared References Behavior
7+
8+
Mutative supports non-unidirectional trees (DAGs with shared nodes) where there is more than one path from the root to the same node, **as long as there are no cycles**. However, there is an important behavior to understand regarding how drafts handle these shared references.
9+
10+
## Independent Drafts for Multiple Paths
11+
12+
When the same object is referenced from multiple paths in the base state, Mutative creates **independent drafts for each path**. This means modifications to one path will **not** automatically reflect in the other paths.
13+
14+
```javascript
15+
import { create } from 'mutative';
16+
17+
const obj = {};
18+
// Same object referenced by two keys
19+
obj.color1 = obj.color2 = { name: 'Red' };
20+
21+
const result = create(obj, (draft) => {
22+
// ⚠️ Different drafts created for each path!
23+
console.log(draft.color1 === draft.color2); // false
24+
25+
draft.color1.name = 'Blue';
26+
27+
// color2 remains unchanged because it has a separate draft
28+
console.log(draft.color2.name); // 'Red'
29+
});
30+
31+
console.log(result.color1 === result.color2); // false
32+
// Result: { color1: { name: 'Blue' }, color2: { name: 'Red' } }
33+
```
34+
35+
This behavior is **by design** and matches Immer's behavior. Each path through the state tree gets its own independent draft proxy.
36+
37+
## Creating Shared References
38+
39+
If you need to **preserve or create shared references** in the result state, you must do so explicitly within your recipe function by assigning one draft to another.
40+
41+
```javascript
42+
const result = create(obj, (draft) => {
43+
draft.color1.name = 'Blue';
44+
45+
// ✅ Explicitly share the reference
46+
draft.color2 = draft.color1;
47+
});
48+
49+
// Now they share the same reference in the result
50+
console.log(result.color1 === result.color2); // true
51+
// Result: { color1: { name: 'Blue' }, color2: { name: 'Blue' } }
52+
```
53+
54+
## Summary
55+
56+
| Scenario | Behavior |
57+
|----------|----------|
58+
| **Shared nodes in base state** | Each path gets its own **independent draft**. Mutations through one path do **not** reflect in other paths. |
59+
| **Manually assigned references** |**Supported**. Assigning `draft.x = draft.y` creates shared references in the final state. |
60+
| **Real cycles** |**Not supported**. Cycles are actively detected in development mode when auto-freeze is enabled. |

0 commit comments

Comments
 (0)