I’ve been trying to find a way for computed values in Zustand for a while. The general recommended way is using a custom hook, according to Daishi Kato himself. The issue with this approach, however, is that your computed logic will be completely alienated from the store itself.
I just found a neat approach which seems to work: using a nested object inside the store itself, as pointed in this highly cheered comment. Below is a fully typed example:
import {create} from 'zustand';
import {combine} from 'zustand/middleware';
import {immer} from 'zustand/middleware/immer';
export interface Person {
name: string;
age: number;
}
const usePeople = create(immer(
combine({
people: [] as Person[],
},
(set, get) => ({
$computed: {
get count(): number {
return get().people.length;
},
},
addNew(name: string, age: number): void {
set(state => {
state.people.push({name, age});
});
},
})),
));
export default usePeople;
The tradeoff, as benchmarked by myself, is that this $computed getters are not cached and will run every time the state changes, in addition to every time they are requested – which happens when the component re-renders. The ordinary custom hook approach runs only when they are requested. So, there is a performance penalty, which can be huge if the logic is too demanding.
No comments:
Post a Comment