Skip to main content

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 function set can access the current state of bears and indeed does so, to then add the by value to it and set the updated value as the new state of bears.

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.