Utilities
Valtio provides a set of utility functions to handle more advanced use cases. These are available under the valtio/utils
entry point.
import { devtools, subscribeKey, watch } from 'valtio/utils';
For vanilla JavaScript projects, import from valtio/vanilla/utils
.
devtools
Integrates your Valtio state with the Redux DevTools Extension for powerful debugging, including state inspection and time-travel.
Usage:
import { proxy } from 'valtio';
import { devtools } from 'valtio/utils';
const state = proxy({ count: 0, text: 'hello' });
// Connect the state to the devtools
const unsubscribe = devtools(state, { name: 'My App State', enabled: true });
subscribeKey
Subscribes to changes of a specific primitive property on a proxy object. The callback is only fired when that particular property's value changes.
Usage:
import { proxy } from 'valtio';
import { subscribeKey } from 'valtio/utils';
const state = proxy({ count: 0, text: 'hello' });
// This callback only runs when `state.count` changes.
subscribeKey(state, 'count', (newCount) => {
console.log('Count changed to:', newCount);
});
state.count++; // Fires the callback
state.text = 'world'; // Does not fire the callback
watch
Creates a reactive effect that tracks multiple proxy objects and re-runs a callback whenever any of them change. The callback receives a get
function to register dependencies.
Usage:
import { proxy } from 'valtio';
import { watch } from 'valtio/utils';
const userState = proxy({ user: { name: 'Juuso' } });
const sessionState = proxy({ expired: false });
const stop = watch((get) => {
// `get` tracks dependencies automatically
const name = get(userState).user.name;
const isExpired = get(sessionState).expired;
console.log(`${name}'s session is ${isExpired ? 'expired' : 'valid'}`);
});
// The callback runs immediately, then again on any change to tracked proxies.
sessionState.expired = true;
// Stop watching for changes
stop();
proxyMap
and isProxyMap
Creates a reactive Map
that is compatible with Valtio. Native Map
objects cannot be tracked, so proxyMap
provides a proxy-based alternative that mimics the Map
API.
Usage:
import { proxyMap } from 'valtio/utils';
const state = proxy({
users: proxyMap([
[1, { name: 'Alice' }],
[2, { name: 'Bob' }],
]),
});
// Mutate it like a normal Map
state.users.set(3, { name: 'Charlie' });
state.users.delete(1);
// Check if an object is a proxyMap
import { isProxyMap } from 'valtio/utils';
isProxyMap(state.users); // true
proxySet
and isProxySet
Creates a reactive Set
that is compatible with Valtio. Similar to proxyMap
, this utility provides a trackable alternative to the native Set
.
Usage:
import { proxySet } from 'valtio/utils';
const state = proxy({
tags: proxySet(['react', 'typescript']),
});
// Mutate it like a normal Set
state.tags.add('valtio');
state.tags.delete('react');
// Check if an object is a proxySet
import { isProxySet } from 'valtio/utils';
isProxySet(state.tags); // true
useProxy
A convenience hook for React that returns a special proxy. You can use this proxy for both reading in the render phase and for mutations in callbacks, simplifying the state
/snapshot
distinction. Note that mutations are only allowed on the root level of the returned proxy.
import { useProxy } from 'valtio/utils';
const state = proxy({ count: 1 });
const Component = () => {
const $state = useProxy(state);
return (
<div>
{$state.count} {/* Read from the proxy in render */}
<button onClick={() => ++$state.count}>+1</button> {/* Mutate it in a callback */}
</div>
);
};
derive
Creates a new derived proxy state from other proxies. The derived values are recomputed whenever the source proxies change.
This utility is available in a separate package: derive-valtio
.
Usage:
import { proxy } from 'valtio';
import { derive } from 'derive-valtio';
const state = proxy({ count: 1 });
const derivedState = derive({
doubled: (get) => get(state).count * 2,
});
// `derivedState.doubled` will be 2
// If `state.count` changes to 5, `derivedState.doubled` will become 10.
proxyWithHistory
Creates a proxy with undo/redo capabilities by tracking a history of snapshots.
This utility is available in a separate package: valtio-history
.
Usage:
import { proxyWithHistory } from 'valtio-history';
const state = proxyWithHistory({ count: 0 });
state.value.count += 1; // count is 1
state.undo(); // count is 0
state.redo(); // count is 1
unstable_deepProxy
A utility to recursively traverse an object and convert all proxiable objects into their Valtio equivalents (proxy
, proxyMap
, proxySet
), respecting objects marked with ref()
.
Usage:
import { unstable_deepProxy as deepProxy } from 'valtio/utils';
const obj = {
mySet: new Set([1]),
myMap: new Map([['a', 1]]),
nested: { value: 'foo' }
};
const proxiedObj = deepProxy(obj);
// proxiedObj.mySet is now a proxySet
// proxiedObj.myMap is now a proxyMap
// proxiedObj.nested is now a proxy