Maison >interface Web >js tutoriel >Zustand, Quand, comment et pourquoi

Zustand, Quand, comment et pourquoi

PHPz
PHPzoriginal
2024-09-03 21:00:40703parcourir

Table des matières

  1. Introduction à la gestion de l'État
  2. Comprendre Zustand
  3. Types d'État
  4. Premiers pas avec Zustand
  5. Principales fonctionnalités de Zustand
  6. Mise en œuvre de Zustand
  7. Zustand par rapport à d'autres solutions de gestion d'État
  8. Conception du système de Zustand
  9. État persistant avec Zustand
  10. Utilisation des composants Zustand en dehors de React
  11. Exemples concrets
  12. Conclusion
  13. Conseils : Gestion du code asynchrone avec Zustand

1. Introduction à la gestion de l'État

La gestion des états est un aspect crucial du développement Web moderne, en particulier dans les applications complexes. Cela implique de gérer les données qui peuvent changer au fil du temps et de garantir que ces données sont représentées de manière cohérente dans l'ensemble de l'application. Une gestion efficace de l'état conduit à des applications plus prévisibles et maintenables.

2. Comprendre Zustand

Zustand est une petite solution de gestion d'état rapide et évolutive pour les applications React. Créé par Jared Palmer et Daishi Kato, Zustand propose une API simple et intuitive qui rend la gestion des états moins lourde par rapport à d'autres solutions.

3. Types d'État

Avant de plonger plus profondément dans Zustand, comprenons les différents types d'état dans les applications Web :

  1. État local : état spécifique à un composant et qui n'a pas besoin d'être partagé avec d'autres parties de l'application.
  2. État global : état auquel plusieurs composants doivent accéder et modifier dans l'application.
  3. État distant : état qui représente les données récupérées à partir d'une source externe, généralement une API.

Zustand excelle dans la gestion de l'État local et mondial et peut être intégré à des solutions de gestion de l'État à distance.

4. Premiers pas avec Zustand

Pour commencer à utiliser Zustand, installez-le d'abord via npm, fil ou pnpm :

npm install zustand
# or
yarn add zustand
# or
pnpm add zustand

5. Principales caractéristiques de Zustand

Zustand est doté de plusieurs fonctionnalités qui le distinguent :

  1. Simplicité : Zustand dispose d'une API minimale, ce qui la rend facile à apprendre et à utiliser.
  2. Pas de passe-partout : contrairement à d'autres solutions de gestion d'état, Zustand nécessite très peu de code de configuration.
  3. Basé sur les Hooks : Zustand exploite React Hooks, ce qui le rend natif du développement React moderne.
  4. Prise en charge de TypeScript : Zustand fonctionne très bien avec TypeScript, offrant une excellente inférence de type.
  5. Prise en charge du middleware : Zustand vous permet d'étendre ses fonctionnalités via un middleware.
  6. Prise en charge des Devtools : Zustand s'intègre bien à Redux DevTools pour le débogage.
  7. Indépendant du framework : bien qu'il soit principalement utilisé avec React, Zustand peut être utilisé dans n'importe quel environnement JavaScript.

6. Implémentation de Zustand

Regardons une implémentation de base de Zustand :

import { create } from 'zustand'

const useStore = create((set) => ({
  bears: 0,
  increasePopulation: () => set((state) => ({ bears: state.bears + 1 })),
  removeAllBears: () => set({ bears: 0 }),
}))

function BearCounter() {
  const bears = useStore((state) => state.bears)
  return <h1>{bears} around here...</h1>
}

function Controls() {
  const increasePopulation = useStore((state) => state.increasePopulation)
  return <button onClick={increasePopulation}>one up</button>
}

Dans cet exemple, nous créons un magasin avec un état ours et deux actions pour le modifier. Les composants BearCounter et Controls peuvent ensuite accéder et modifier l'état à l'aide du hook useStore.

7. Zustand par rapport à d'autres solutions de gestion d'état

Comparons Zustand avec d'autres solutions de gestion d'État populaires :

Zustand contre Redux

Avantages de Zustand :

  • API plus simple avec moins de passe-partout
  • Pas besoin de créateurs d'action ou d'instructions de commutation
  • Taille du paquet plus petite

Inconvénients :

  • Écosystème moins établi
  • Moins d'options middleware

Zustand contre MobX

Avantages de Zustand :

  • API plus simple et moins magique
  • Meilleures performances pour les applications plus volumineuses

Inconvénients :

  • Moins réactif par défaut
  • Aucune valeur calculée prête à l'emploi

Zustand contre Recul

Avantages de Zustand :

  • Modèle mental plus simple
  • Fonctionne en dehors de React

Inconvénients :

  • Moins de réactivité granulaire
  • Aucun concept de famille d'atomes intégré

8. Conception du système de Zustand

La conception du système Zustand est basée sur quelques principes clés :

  1. Single store: Zustand encourages the use of a single store for all application state.
  2. Immutability: State updates are handled immutably, ensuring predictable behavior.
  3. Subscriptions: Components subscribe to specific parts of the state, re-rendering only when those parts change.
  4. Middleware: Zustand uses a middleware system for extending functionality.

This design allows Zustand to be both simple and powerful, providing excellent performance even in large applications.

9. Persisting State with Zustand

Zustand makes it easy to persist state, which is crucial for many applications. Here's an example using the persist middleware:

import { create } from 'zustand'
import { persist } from 'zustand/middleware'

const useStore = create(persist(
  (set, get) => ({
    fishes: 0,
    addAFish: () => set({ fishes: get().fishes + 1 }),
  }),
  {
    name: 'food-storage', // unique name
    getStorage: () => localStorage, // (optional) by default, 'localStorage' is used
  }
))

This will automatically save the state to localStorage and rehydrate it when the app reloads.

10. Using Zustand Outside React Components

One of Zustand's strengths is that it can be used outside of React components. This is particularly useful for integrating with other parts of your application or for testing:

const { getState, setState } = useStore

// Getting state
console.log(getState().bears)

// Setting state
setState({ bears: 10 })

// Using actions
getState().increasePopulation()

11. Real-World Examples

Let's look at some real-world examples of using Zustand:

Authentication State

import { create } from 'zustand'

const useAuthStore = create((set) => ({
  user: null,
  isAuthenticated: false,
  login: (userData) => set({ user: userData, isAuthenticated: true }),
  logout: () => set({ user: null, isAuthenticated: false }),
}))

// Usage in a component
function LoginButton() {
  const { isAuthenticated, login, logout } = useAuthStore()

  const handleAuth = () => {
    if (isAuthenticated) {
      logout()
    } else {
      // Simulate login
      login({ id: 1, name: 'John Doe' })
    }
  }

  return (
    <button onClick={handleAuth}>
      {isAuthenticated ? 'Logout' : 'Login'}
    </button>
  )
}

Shopping Cart

import { create } from 'zustand'

const useCartStore = create((set) => ({
  items: [],
  addItem: (item) => set((state) => ({ items: [...state.items, item] })),
  removeItem: (itemId) => set((state) => ({
    items: state.items.filter((item) => item.id !== itemId),
  })),
  clearCart: () => set({ items: [] }),
  total: 0,
  updateTotal: () => set((state) => ({
    total: state.items.reduce((sum, item) => sum + item.price, 0),
  })),
}))

// Usage in components
function CartSummary() {
  const { items, total, removeItem } = useCartStore()

  return (
    <div>
      {items.map((item) => (
        <div key={item.id}>
          {item.name} - ${item.price}
          <button onClick={() => removeItem(item.id)}>Remove</button>
        </div>
      ))}
      <div>Total: ${total}</div>
    </div>
  )
}

Theme Switcher

import { create } from 'zustand'
import { persist } from 'zustand/middleware'

const useThemeStore = create(persist(
  (set) => ({
    theme: 'light',
    toggleTheme: () => set((state) => ({
      theme: state.theme === 'light' ? 'dark' : 'light',
    })),
  }),
  {
    name: 'theme-storage',
  }
))

// Usage in a component
function ThemeToggle() {
  const { theme, toggleTheme } = useThemeStore()

  return (
    <button onClick={toggleTheme}>
      Switch to {theme === 'light' ? 'dark' : 'light'} mode
    </button>
  )
}

12. Conclusion

Zustand offers a refreshing approach to state management in React applications. Its simplicity, flexibility, and performance make it an excellent choice for both small and large projects. By reducing boilerplate and providing a straightforward API, Zustand allows developers to focus on building features rather than managing complex state logic.

While it may not have the extensive ecosystem of some older state management solutions, Zustand's design principles and ease of use make it a compelling option for modern React development. Its ability to work outside of React components and easy integration with persistence solutions further extend its utility.

For many React applications, Zustand strikes an excellent balance between simplicity and power, making it worth considering for your next project.

Bonus tips:

Zustand also handles asynchronous functions/code really well and without the need for any Middleware setup.

Let's talk a bit about that:

13. Handling Asynchronous Code with Zustand

One of Zustand's strengths is its simplicity in handling asynchronous operations without the need for additional middleware or complex setups. This makes it particularly easy to work with API calls, data fetching, and other asynchronous tasks.

How Zustand Handles Asynchronous Code

Zustand's approach to asynchronous code is straightforward:

  1. Direct Integration: Asynchronous functions can be defined directly in the store.
  2. No Special Syntax: You don't need to use special action creators or thunks.
  3. State Updates: You can update the state within async functions using the set function.
  4. Error Handling: Error states can be managed directly within the async functions.

Implementing Asynchronous Code

Here's an example of how to implement asynchronous code in Zustand:

import { create } from 'zustand'

const useUserStore = create((set) => ({
  user: null,
  isLoading: false,
  error: null,
  fetchUser: async (userId) => {
    set({ isLoading: true, error: null });
    try {
      const response = await fetch(`https://api.example.com/users/${userId}`);
      if (!response.ok) throw new Error('Failed to fetch user');
      const userData = await response.json();
      set({ user: userData, isLoading: false });
    } catch (error) {
      set({ error: error.message, isLoading: false });
    }
  },
}));

// Usage in a component
function UserProfile({ userId }) {
  const { user, isLoading, error, fetchUser } = useUserStore();

  React.useEffect(() => {
    fetchUser(userId);
  }, [userId]);

  if (isLoading) return <div>Loading...</div>;
  if (error) return <div>Error: {error}</div>;
  if (!user) return null;

  return (
    <div>
      <h1>{user.name}</h1>
      <p>Email: {user.email}</p>
    </div>
  );
}

In this example:

  1. We define an async fetchUser function directly in the store.
  2. The function manages loading and error states alongside the user data.
  3. We use the set function to update the state at different points in the async operation.
  4. In the component, we can use the store's state and actions as usual, with React hooks handling the component lifecycle.

Benefits of Zustand's Approach to Async Code

  1. Simplicity: No need for additional middleware or complex action creators.
  2. Flexibility: You can structure your async logic however you prefer.
  3. Readability: Async operations are defined close to the relevant state.
  4. Easy Testing: Async functions can be easily unit tested.

Comparison with Other Solutions

Unlike Redux, which often requires middleware like Redux Thunk or Redux Saga for handling async operations, Zustand's approach is much more straightforward. This simplicity can lead to less boilerplate and a gentler learning curve, especially for developers new to state management.

MobX and Recoil also offer ways to handle async operations, but Zustand's approach might be considered more intuitive due to its direct use of async/await syntax without additional abstractions.

En conclusion pour l'async

La gestion du code asynchrone par Zustand illustre sa philosophie de simplicité et de flexibilité. En permettant aux développeurs d'écrire des fonctions asynchrones directement dans le magasin sans syntaxe particulière ni middleware, Zustand facilite la gestion des opérations d'état complexes tout en gardant la base de code propre et lisible.

Cette approche du code asynchrone, combinée aux autres fonctionnalités de Zustand telles que sa petite taille de bundle et sa configuration facile, en fait un excellent choix pour les projets de toutes tailles, en particulier ceux qui impliquent une gestion d'état asynchrone importante.

J'espère que ce « un peu guide » a été utile et instructif pour tous ceux d'entre vous qui réfléchissent à la façon de gérer l'état global de leur application.
Merci et bon codage.

Jetez un oeil sur mon site Web à https://www.ricardogesteves.com

Suivez-moi @ricardogesteves
X(twitter)

Zustand, When, how and why

RicardoGEsteves (Ricardo Esteves) · GitHub

Développeur Full-Stack | Passionné par la création d'expériences utilisateur intuitives et percutantes | Basé à Lisbonne, Portugal ?? - Ricardo GEsteves

Zustand, When, how and why github.com

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn