-
Hello, I need some opinions on what would be the best way to set up computed/derived data in valtio store. 1. Store a function inside valtio const state = proxy({
count: 1,
doubled: () => state.count * 2
}) 2. Use import { addComputed } from 'valtio/utils'
const state = proxy({
count: 1,
})
// add computed to state
addComputed(state, {
doubled: snap => snap.count * 2,
}) Are there any issues using approach in the first approach? For the record I'm using React and the following part in the documentation left me confused. Dependency tracking in valtio conflicts with the work in useSnapshot. React users should consider using render functions (optionally useMemo) as a primary mean. Computed works well for some edge cases and for vanilla-js users. Thank you in advance and thank you @dai-shi for this simple and clean state library! |
Beta Was this translation helpful? Give feedback.
Replies: 2 comments 16 replies
-
Thanks for opening this up. There are pros/cons, and can't recommend "one" way. state function to get state (computed) valueconst state = proxy({
count: 1,
doubled: () => state.count * 2
}) This code alone is valid and const Component = () => {
const { doubled } = useSnapshot(state)
return <div>{doubled()}</div>
} This is not reactive because state function with
|
Beta Was this translation helpful? Give feedback.
-
I might be doing something wrong but I don't find out where I did it when I used the custom hook proposed to be a solution (see below): I still get the linting error "better to just use proxy state". const useDoubled = () => {
const snap = useSnapshot(state)
return snap.count * 2
^^^^ Better to just use proxy state.eslint(valtio/state-snapshot-rule)
} When you don't want to modify the state but just render a modified state, then the linter is happy and the component is reactive when you modify the snap directly in the return. But this usage may be somehow of little interest. const doubled = c => c*2
const Component = () => {
const {count} = useSnapshot(store)
return <p>{doubled(count)}</p>
} Any comment/update? If I want to modify the state within a component, then a callback acting on the state and triggered by a button will render. But this is also a limited use case const store = proxy({
count: 0,
double: ()=> store.count *= 2
})
const Component = () => {
const snap = useSnapshot(store)
const action = ()=> store.double()
return( <>
<button onClick={action}>double</button>
{snap.count}
</>)
} |
Beta Was this translation helpful? Give feedback.
Thanks for opening this up. There are pros/cons, and can't recommend "one" way.
state function to get state (computed) value
This code alone is valid and
state.dobuled()
works just fine.However, there's a pitfall when using with
useSnapshot
:This is not reactive because
doubled
is reading a mutablestate
object. So, even ifcount
changes, this component won't re-render.state function with
this
that works with snapshotTo do it correctly, here's the solution.