watch
This utility behaves similarly to useEffect
in React. Proxy objects are tracking with a get
function passed to the callback. Notice the callback will run eagerly as soon as a proxy is tracked, even if not yet mutated.
import {proxy} from 'valtio'
import {watch} from 'valtio/utils'
const userState = proxy({ user: { name: 'Juuso' } })
const sessionState = proxy({ expired: false })
watch((get) => {
const expired = get(sessionState).expired
const name = get(userState).user.name
console.log(`${name}'s session is ${expired ? 'expired' : 'valid'}`)
})
// 'Juuso's session is valid'
sessionState.expired = true
// 'Juuso's session is expired'
cleanup
You may return a callback function that runs after watch has evaluated its dependencies.
watch((get) => {
const expired = get(sessionState).expired
const name = get(userState).user.name
console.log(`${name}'s session is ${expired ? 'expired' : 'valid'}`)
return () => {
if (expired) {
console.log('Cleaning up')
}
}
})
// 'Juuso's session is valid'
sessionState.expired = true
// 'Juuso's session is expired'
setTimeout(() => {
userState.user.name = "Anonymous"
}, 200)
// 200ms -> 'Anonymous's session is expired"
// 'Cleaning up' logged
Gotchas
If you remove the setTimeout in the example above, 'Juuso's session is expired' will become 'Anonymous's session is expired', logged twice now. Valtio will batch updates by default. You may pass {sync: true}
as a second argument to watch
to disable batching. However, this is relatively untested and should be used with caution.