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:
- Gestione nativa dello stato
useState
useReducer
useRef
useContext
- Gestori di stato indiretti
- Gestori di stato diretti
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:
- Performance superiore rispetto al contesto nativo
useContext
- Unione automatica dello stato
{x: 1, y: 2}
{y: 3}
{x: 1, y: 3}
- Estendibilità
- Flessibilità e semplicità
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
- Action creators
- Dispatcher store
- Reducers
- Store
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
- 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.