Zustand
For our TaskFlow web app we used Context
to handle state across multiple components. As this can have a few downsides which we'd rather avoid (refer back to the further reading section in the React Context chapter to see what these were), we're going to get acquainted with a library that aims to remedy these pitfalls. It is called Zustand
. As they proudly state themselves, compared to Context
it involves less boilerplate, renders components only on changes and centralizes your state management. Very convenient! To get installing, run:
npm i zustand
Zustand
requires us to write a hook that will become our store, as shown here.
import { create } from 'zustand'
interface BearState {
bears: number
increase: (by: number) => void
}
const useBearStore = create<BearState>()((set) => ({
bears: 0,
increase: (by) => set((state) => ({ bears: state.bears + by })),
}))
Let's break this code snippet down and see what is actually happening. The library provides us with a create
function that expects us to pass a callback function. This callback takes a set argument and returns an object with:
-
Our state, in this case
bears
of type number. -
A function to change this state, in this case called
increase
. Notice how in this functionset
can access the current state of bears and indeed does so, to then add theby
value to it and set the updated value as the new state ofbears
.
This hook can then be used in your code like this:
// Some component that displays the amount of bears
const bears = useBearStore((state) => state.bears);
<Text>The amount of bears this app contains is {bears}</Text>
// Some component that updates the amount of bears
const increase = useBearStore((state) => state.increase);
const handlePress = () => {
increase(1);
}
<Pressable onPress={handlePress} />
Now every time the button gets pressed the text will be updated with the new amount of bears.
As mentioned in the guide you can also choose to do multiple state-picks at the same time, i.e. when you need to do a lot of state handling in one place.
const { bears, increase } = useBearStore(
(state) => ({ bears: state.bears, increase: state.increase }),
shallow
);
And that's basically it! Time to try and set up a store of your own. Make one for timeEntries
and teamMembers
and replace all occurences of useState
.