Valtio does not maintain nested subscriptions when object is replaced entierly #1149
Replies: 2 comments 2 replies
-
|
Yes. .Valtio will use object references for comparison for value changes rather than checking property names, When you replace a property with another object, even if the property name is the same, it will have a different object reference. This is not a bug, but rather both how javascript works and how valtio decided to make perfomance important by not needing to do deep comparison on every property change. An example of how plain javascript works... const foo = {
nested: {
bar: {
baz: 5
}
}
}
// if we create a new object with the same properties, they will not be "===" to eachother
// copy all property names and values to a new object
const foo2 = {...foo}
console.log(foo2 === foo) // false
// if we just pass the objects through assignments though, they keep their references and can be compared using equality operator
const prop1 = foo.nested
const prop2 = prop1.bar
console.log(prop2 === foo.nested.bar) // trueSince you are replacing state with a newly created object referencel, it will always be different to what was subsribed to previously. |
Beta Was this translation helpful? Give feedback.
-
|
It's a designed limitation. If you replace the entire object, do this instead: const { world: { whatever } } = useSnapshot(hello) |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
Bug Description
If we have subscriptions like
useSnapshot(hello.world.whatever), and if.whateveror.world.whateveris replaced likehello.world = {whatever: {puper: 10}}, this subscription will not re-render component. This causes libraries likevaltio-yjsbeak granular subscriptions.Reproduction Link
https://stackblitz.com/edit/valtio-does-not-maintain-subscriptions
Beta Was this translation helpful? Give feedback.
All reactions