-
I've been playing around with Valtio for the last month or so. I've dug through the documentation, read github discussion, and looked at the eslint repository, but the one thing that I haven't been able to figure out is how valtio can be used (if at all) with react hooks. useEffect useEffect can somewhat be achieved by subscribing to valtio state within the hook, as prescribed here. This deregisters the function when the component unmounts, and will redefine it if non-valtio hook dependencies change. The pattern is a bit confusing, but it should work. useMemo/useCallback This case is more problematic, as the return value is used elsewhere within the component. Option 1: use the snapshot It's well-documented to not pass snapshots as hook dependencies. The eslint plugin does its best to try and prevent it. This is the best explanation I've found for why it's a bad idea - it may work, but depending on what properties of the snapshot are accessed, it may not. Option 2: use the proxy This won't work because the proxy is mutable. When passed as a hook dependency, it will not redefine itself correctly when the proxy changes, and will begin working off of stale data. Omitting it as a hook dependency also won't work since it will fail to re-run when the proxy changes as well (in addition to breaking the react exhaustive-deps rule). Option 3: destructure to primitives If the snapshot is used and descructured all the way down to primitives, this approach should work. This avoids the conditional access problem introduced in option 1. However, this is not a pattern that can be applied to all use cases. It's quite common that you need to work with an entire object, at which point you'd need to fully destructure and then recreate the object inside of the hook. The developer ergonomics of this are poor, to say the least. Option 4: don't use hooks Given the above, the only conclusion that I've been able to come to is to forego using component level hooks entirely. Instead, everything must be hoisted into the valtio state. Proxy-memoize or another library can be used to achieve memoization for these actions. However, this means that all component-specific logic must now live in the global state instead of inside the corresponding component. Code-splitting techniques outlined in the documentation can possibly be used to locate component-specific valtio actions away from the primary state, but overall this approach forces a fundamentally different pattern for mixing component-level and valtio state. Does this sound accurate? I'd love to be wrong. |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 3 replies
-
This will be improved with less optimization in Valtio v2. |
Beta Was this translation helpful? Give feedback.
This will be improved with less optimization in Valtio v2.
See: #866
See also: https://twitter.com/dai_shi/status/1764115879737123188 https://twitter.com/dai_shi/status/1766279254084550705 https://twitter.com/dai_shi/status/1763701256105922719