Nessun risultato. Prova con un altro termine.
Guide
Notizie
Software
Tutorial

React: gestione dello stato con Zustand

React: Zustand è una libreria semplice ma potente che semplifica la gestione dello stato quando si lavora con il framework front-end
React: Zustand è una libreria semplice ma potente che semplifica la gestione dello stato quando si lavora con il framework front-end
Link copiato negli appunti

La gestione dello stato è una parte cruciale nello sviluppo di applicazioni React. Ti sei mai trovato in difficoltà a gestire lo stato della tua applicazione e ti sei chiesto quale libreria potesse semplificarti il lavoro? Se la risposta è sì, allora questo articolo fa al caso tuo. Scoprirai come gestire lo stato in React utilizzando una libreria leggera ed efficiente chiamata Zustand.

Perché la gestione dello stato è importante in React?

Lo stato e la sua gestione sono pilastri fondamentali in ogni applicazione React. Il framework funziona sulla base del principio di aggiornamento del rendering: il DOM virtuale viene aggiornato solo quando lo stato cambia. Lo stato può contenere dati o informazioni relative ad un componente, come l'interazione dell'utente o i valori che determinano il comportamento della UI. Man mano che l'applicazione cresce, mantenere il controllo sullo stato e sulla sua propagazione tra i componenti diventa sempre più complesso. In questo contesto, una soluzione solida per la gestione dello stato è quindi indispensabile.

Le opzioni per la gestione dello stato in React

Esistono diversi approcci per gestire lo stato in un'applicazione React:

  1. Gestione nativa dello stato: utilizzando hook come useStateuseReduceruseRefuseContext e hook personalizzati, React offre strumenti potenti per una gestione dello stato integrata. Per applicazioni più grandi questi strumenti possono però diventare difficili da gestire e mantenere.
  2. Gestori di stato indiretti: librerie come React Router o React Query non sono specificamente progettate per la gestione dello stato ma possono essere combinate con gli strumenti nativi per coprire determinati casi d'uso.
  3. Gestori di stato diretti: librerie di terze parti, come Redux, Zustand, Jotai e Valtio, sono progettate per la gestione dello stato e offrono soluzioni scalabili e modulari.

Tra queste ultime Zustand si distingue per la sua semplicità ed efficacia.

Cos'è Zustand?

Zustand è una libreria per la gestione dello stato in React che si distingue per la sua compattezza, velocità e scalabilità. Il termine "Zustand" significa "stato" in tedesco ed è progettata per ridurre al minimo il codice, evitando l'uso di boilerplate complessi come quelli richiesti da altre librerie. Ad esempio Redux.

Zustand si basa su principi semplificati del modello Flux e sfrutta principalmente gli hook per la gestione dello stato. La sua flessibilità consente di adattarsi a molteplici casi d'uso senza vincoli rigidi.

Perché scegliere Zustand?

Ecco alcune caratteristiche che rendono Zustand un'opzione interessante:

  1. Performance superiore rispetto al contesto nativo: grazie ad una gestione ottimizzata dello stato, Zustand è più veloce di useContext, soprattutto in applicazioni più complesse.
  2. Unione automatica dello stato: con Zustand, puoi aggiornare singole proprietà dello stato senza dover diffondere manualmente l'intero stato precedente. Ad esempio, per aggiornare un oggetto {x: 1, y: 2} con {y: 3}, Zustand si occupa automaticamente di unire i dati in {x: 1, y: 3}.
  3. Estendibilità: la libreria è compatibile con diversi tipi di middleware, consentendo di aggiungere funzionalità come la persistenza dello stato o strumenti di debugging.
  4. Flessibilità e semplicità: non impone un modello rigido di utilizzo. Anche se esistono delle best practice hai la libertà di adottare lo stile più adatto al tuo progetto.

Confronto tra Zustand e Redux

Redux è la libreria più popolare per la gestione dello stato in React, nota per la sua solidità e l'adozione diffusa. Tuttavia, il suo approccio architetturale può risultare complesso e richiedere una quantità significativa di boilerplate. Per comprendere meglio, diamo uno sguardo alle due architetture.

Architettura di Redux

L'architettura Redux è composta da diversi elementi:

  • UI: rappresenta il front-end.
  • Action creators: generano azioni che descrivono un evento nell'applicazione, come il clic su un pulsante.
  • Dispatcher: invia le azioni allo store.
  • Reducers: funzioni che, partendo dallo stato corrente e dall'azione ricevuta, calcolano il nuovo stato.
  • Store: contiene lo stato globale.

Mentre questa struttura è potente può diventare rapidamente complessa, soprattutto per progetti di dimensioni ridotte o medie.

Architettura di Zustand

L'architettura di Zustand è molto più semplice:

  • La UI si collega direttamente allo store.
  • Non ci sono action creators, dispatcher o reducers. Zustand consente di iscriversi direttamente alle modifiche dello stato, rendendo la sincronizzazione dei dati con la UI più immediata.

Questa semplicità rende Zustand ideale per sviluppatori che cercano una soluzione leggera ed efficace.

Come utilizzare Zustand in un progetto React?

Vediamo un esempio pratico. Creeremo un'applicazione chiamata Library Store, che tiene traccia dei libri disponibili e di quelli prestati.

Creare un'applicazione React

Per prima cosa, creiamo una nuova applicazione React con il comando:

npx create-react-app library-store

Installare la dipendenza di Zustand

Spostati nella directory del progetto e installa Zustand:

npm install zustand

Creare uno store

Crea un file bookStore.js e definisci lo store con Zustand:

import { create } from "zustand";
const bookStore = (set, get) => ({
  books: [],
  noOfAvailable: 0,
  noOfIssued: 0,
  addBook: (book) => {
    set((state) => ({
      books: [...state.books, { ...book, status: "available" }],
      noOfAvailable: state.noOfAvailable + 1,
    }));
  },
  issueBook: (id) => {
    const books = get().books;
    const updatedBooks = books.map((book) =>
      book.id === id ? { ...book, status: "issued" } : book
    );
    set((state) => ({
      books: updatedBooks,
      noOfAvailable: state.noOfAvailable - 1,
      noOfIssued: state.noOfIssued + 1,
    }));
  },
  returnBook: (id) => {
    const books = get().books;
    const updatedBooks = books.map((book) =>
      book.id === id ? { ...book, status: "available" } : book
    );
    set((state) => ({
      books: updatedBooks,
      noOfAvailable: state.noOfAvailable + 1,
      noOfIssued: state.noOfIssued - 1,
    }));
  },
  reset: () => {
    set({ books: [], noOfAvailable: 0, noOfIssued: 0 });
  },
});
const useBookStore = create(bookStore);
export default useBookStore;

Questo store contiene lo stato dell'applicazione e le funzioni per modificarlo.

Collegare i componenti allo store

import { useEffect } from "react";
import BookForm from "./components/BookForm";
import BookList from "./components/BookList";
import useBookStore from "./bookStore";
function App() {
  const reset = useBookStore((state) => state.reset);
  useEffect(() => reset(), [reset]);
  return (
    <div>
      <h2>Library Store</h2>
      <BookForm />
      <BookList />
    </div>
  );
}
export default App;

Di seguito, invece, il file BookForm.js:

import { useState } from "react";
import useBookStore from "../bookStore";
function BookForm() {
  const addBook = useBookStore((state) => state.addBook);
  const [bookDetails, setBookDetails] = useState({});
  const handleChange = (e) =>
    setBookDetails({ ...bookDetails, [e.target.name]: e.target.value });
  return (
    <div>
      <input name="id" onChange={handleChange} placeholder="Book ID" />
      <input name="name" onChange={handleChange} placeholder="Book Name" />
      <input name="author" onChange={handleChange} placeholder="Author" />
      <button onClick={() => addBook(bookDetails)}>Add Book</button>
    </div>
  );
}
export default BookForm;

ed ecco il file BookList.js:

import useBookStore from "../bookStore";
function BookList() {
  const { books, issueBook, returnBook } = useBookStore();
  return (
    <ul>
      {books.map((book) => (
        <li key={book.id}>
          {book.name} - {book.status}
          <button
            onClick={() => issueBook(book.id)}
            disabled={book.status === "issued"}
          >
            Issue
          </button>
          <button
            onClick={() => returnBook(book.id)}
            disabled={book.status === "available"}
          >
            Return
          </button>
        </li>
      ))}
    </ul>
  );
}
export default BookList;

Conclusioni

Zustand è una libreria semplice, ma potente, che semplifica notevolmente la gestione dello stato in React. Grazie alla sua flessibilità, può essere utilizzata per progetti di qualsiasi dimensione, dal più piccolo al più complesso.

Ti consigliamo anche