1. Utils
  2. watch

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.