-
I was debugging how I can react on state updates with useEffect. But the results between working with the state object directly as a dependency or using the snapshot, was quite confusing. Sometimes both work sometimes working directly with the state object did not trigger the useEffect callback function. Can someone give me guidance which one of these options I should use: // with state object directly
useEffect(() => {
console.log('do magic with', state.watchObj)
}, [state.watchObj]) // with snapshot
useEffect(() => {
console.log('do magic with', snapShot.watchObj)
}, [snapShot.watchObj]) // with subscribe
useEffect(() => {
const callback = () => {
console.log('do magic with', state.watchObj)
}
const unsubscribe = subscribe(state.watchObj, callback)
callback()
return () => {
unsubscribe()
}
}, []) Is really the last option the way to go, or can I use one of the slimmer versions above? |
Beta Was this translation helpful? Give feedback.
Replies: 2 comments 13 replies
-
Yeah, you are hitting the difficult part of proxy state. If you want to use useEffect deps, the recommendation is to extract primitive values from snapshot in render, and pass them: const snap = useSnapshot(state)
const { num, string, bool } = snap.watchObj
useEffect(() => {
...
}, [num, string, bool]) This also applies to |
Beta Was this translation helpful? Give feedback.
-
I am using functional components, where everything defined in the function's body is the render function.
This makes my brain hurt a little. So what is your guidance in a case like that: useEffect(() => {
// state.results = [...] // has many values in array
let local = false
if(conditionThatIsTrueOnlyOnce === true) {
state.results = []
local = true
}
if(snap.results.length === 0 && local === true){
console.log('will this trigger or not?')
}
} , [deps]) Is this a timing issue, since the update of state and reading of the snapshot happens too quickly? Am I missing something here? |
Beta Was this translation helpful? Give feedback.
Yeah, you are hitting the difficult part of proxy state.
The last option is actually preferable and less error-prone.
If you want to use useEffect deps, the recommendation is to extract primitive values from snapshot in render, and pass them:
This also applies to
useMemo
anduseCallback
deps, and alsomemo
.We should add notes in https://github.com/pmndrs/valtio/wiki/Some-gotchas.