React State Management mit Zustand

Mit Zustand kann globaler State einer React Anwendung einfacher gemanaged werden

Last updated on 31. Januar 2021
By Timon Grassl
Table of contents

Wenn man in seiner React an den Punkt gelangt an dem das State Management komplexer wird, steht man schnell vor der Wahl einiger verschiedenen Bibliotheken wie react-redux, mobx oder recoil. In diesem Artikel möchte ich eine meiner Lieblingsvarianten vorstellen: zustand.

Trotz der geringen Größe (Unter 1kB minified + gezipped) bietet zustand alle Notwendigkeiten für das State Management in React. Die komplette API basiert auf React Hooks, ist einfach zu nutzen und kann mit eigenen Middlewares angepasst werden.

Beispiel

Als Beispiel habe ich eine kleine React App gebaut, die eine Art „Website-Editor“ darstellen soll.



Sie besteht aus den folgenden Bereichen:

  • Form: Das Formular um Änderungen einzugeben

  • Preview: Eine Live Vorschau der eingegebenen Änderungen

In so einem typischen Szenario wird ein globaler State benötigt, der als „single source of truth“ agiert. So können andere Komponenten sich auf den globalen State verlassen und zusätzlich wird vermieden den State über Props an Komponenten weiterzureichen.

Da in diesem Beispiel zustand als State Management genutzt wird, kann hier auch auf die Umhüllung von einem Context Provider verzichtet werden.

Nutzung

Um zustand einzusetzen muss in der App ein neuer Store als Hook erstellt werden. In meinem Fall habe ich eine neue Datei erstellt (app.state.js), die folgende Funktion exportiert:

import create from "zustand";

export const useAppStore = create((set) => ({
  title: "MyProduct - 30 day free trial",
  description: `Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do  eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad  minim veniam, quis nostrud exercitation ullamco laboris nisi ut  aliquip ex ea commodo consequat. Duis aute irure dolor in  reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla  pariatur. Excepteur sint occaecat cupidatat non proident, sunt in  culpa qui officia deserunt mollit anim id est laborum.`,
  setTitle: (title) => set((state) => ({ title })),
  setDescription: (description) => set((state) => ({ description }))
}));

Mit import create from "zustand" wird hier die Funktion zum Erstellen eines Stores von zustand importiert und dann eine Zeile weiter aufgerufen. set ist eine Funktion, die zustand mitreicht um den state zu modifizieren. Zusätzlich kann man noch get hinzufügen, wenn man den gesamten State später benötigt.

In der create Funktion kann nun der Inhalt des State definiert werden, wie z.B. die einzelnen Properties und Reducer Funktionen um die Properties zu ändern. Reducer können natürlich auch asynchron sein, zustand ist das egal.

Da es sich bei dem Store um eine Hook handelt, kann er einfach in Funktionalen Komponenten genutzt werden. In der Form.js Komponente wird zum Beispiel der setTitle und setDescription Reducer genutzt, um neue Werte für den Titel und die Beschreibung zu setzen.

const setTitle = useAppStore((state) => state.setTitle);
const setDescription = useAppStore((state) => state.setDescription);

const handleTitleChange = (ev) => {
   setTitle(ev.target.value);
};

const handleDescriptionChange = (ev) => {
    setDescription(ev.target.value);
};

Erst wird über die vorhin definierte Hook useAppStore der jeweilige Reducer selektiert. Danach kann dieser mit dem neuen Wert aufgerufen werden. Um am Schluss die Daten in der Vorschau anzuzeigen, wird genau wie beim Formular die useAppStore Hook genutzt. Dabei werden statt den Reducern die Properties selektiert.

const title = useAppStore((state) => state.title);
const description = useAppStore((state) => state.description);

Diese enthalten so immer die neuesten Werte aus dem AppStore.

Wenn diese Bibliothek dein Interesse geweckt hat und du mehr über zustand erfahren möchtest empfehle ich die offizielle Dokumentation auf GitHub ⭐(https://github.com/pmndrs/zustand)

Table of contents
Timon Grassl
Software Engineer
Timon Grassl
Software Engineer