-
-
Notifications
You must be signed in to change notification settings - Fork 260
Some gotchas
https://github.com/pmndrs/valtio/issues/209#issuecomment-896859395
Suppose we have this state (or store).
const state = proxy({
obj: {
count: 0,
text: 'hello',
},
})
If using the snapshot with accessing count,
const snap = useSnapshot(state)
snap.obj.count
it will re-render only if count
changes.
If the property access is obj,
const snap = useSnapshot(state)
snap.obj
then, it will re-render if obj
changes. This includes count
changes and text
changes.
Now, we can subscribe to the portion of the state.
const snapObj = useSnapshot(state.obj)
snapObj
This is technically same as the previous one. It doesn't touch the property of snapObj
, so it will re-render if obj
changes.
In summary, if a snapshot object (nested or not) is not accessed with any properties, it assumes the entire object is accessed, so any change inside the object will trigger re-render.
Object.keys(state.obj)
doesn't touch any object properties, so the same as above.
It's possible to use non-proxy rendering:
const [keys, setKeys] = useState([]);
useEffect(() => {
const callback = () => {
const next = Object.keys(state.obj);
setKeys((prev) => (prev.length === next.length && prev.every((k) => next.includes(k)) ? prev: next);
}
const unsubscribe = subscribe(state.obj, callback);
callback(); // run just once
return unsubscribe;
}, [])