Maison >interface Web >js tutoriel >Gestion de l'état dans Reactjs : un guide pour choisir le bon outil de gestion de l'état pour vos projets

Gestion de l'état dans Reactjs : un guide pour choisir le bon outil de gestion de l'état pour vos projets

PHPz
PHPzoriginal
2024-07-21 08:19:19410parcourir

State Management in Reactjs: A Guide to Choosing the Right State Management Tool for Your Projects

La gestion de l'état est cruciale dans les applications React car elle permet de garder une trace des données des applications. Étant donné que l'interface utilisateur (UI) est fonction de l'état, il est essentiel de garantir que l'état de votre application est toujours à jour. Dans cet article, vous apprendrez comment choisir le bon outil de gestion d'état pour répondre aux exigences de votre application.

Remarque : cet article s'adresse aux développeurs qui ont déjà des connaissances sur React mais souhaitent faire de meilleurs choix pour leurs applications React basées sur la gestion de l'état. Si vous ne savez pas encore réagir, consultez la documentation pour commencer à apprendre.

Comprendre l'État et la gestion de l'État.

Sur la base du prérequis indiqué ci-dessus, vous avez probablement déjà des connaissances sur React. Mais rafraîchissons-nous un peu la mémoire.

Qu’est-ce que l’État ?

L'état dans React est la mémoire d'un composant, contenant des informations spécifiques à ce composant. En termes de programmation, l'état est un objet JavaScript qui contient simplement des données concernant un composant.

Comme mentionné précédemment, l'interface utilisateur de React est directement influencée par l'état. Les changements d'état se produisent principalement en raison des interactions de l'utilisateur telles que les clics sur des boutons, les événements de souris, les actions de saisie, etc. Par conséquent, la gestion de l'état dans nos applications est essentielle pour garantir que les utilisateurs bénéficient de l'interface la plus récente sur leur écran en fonction de leurs interactions.

Gestion de l'état dans React.

Lorsque l'état d'un composant React change, le composant est restitué. Au cours de ce processus, le composant est détruit et reconstruit à partir de zéro en coulisses.

La plupart des applications React subissent de nombreuses mises à jour d'état lorsque les utilisateurs interagissent avec l'application. Il est important d’utiliser la meilleure technique de gestion d’état pour améliorer l’expérience utilisateur ; après tout, utiliser une application qui ne répond pas n’est pas attrayant. Imaginez que vous cliquez sur le bouton J'aime de votre application Instagram et qu'elle ne répond pas. Ennuyeux, non ?

Sans plus tard, examinons les différentes options de gestion d'état que vous pouvez explorer pour votre projet, en expliquant quand et pourquoi vous avez besoin de chacune.

Différentes options de gestion d'état dans React.

Il existe de nombreuses options de gestion d'état disponibles, mais dans cet article, nous aborderons certaines des options les plus couramment utilisées qui s'adressent aux applications de toutes tailles, des petites aux extrêmement grandes. Les options dont nous discuterons incluent :

  • Hooks intégrés React
  • API de contexte
  • Bibliothèques tierces

React hooks intégrés pour la gestion de l'état

React fournit des hooks intégrés pour gérer l'état avec des composants fonctionnels. Ces crochets sont faciles à utiliser et sont parfaits pour la gestion locale de l'État.

L'état local est l'état qui n'est nécessaire que par un seul composant et n'affecte aucun autre composant.

L'état global est l'état nécessaire à plusieurs composants, et nous expliquerons également comment le gérer plus loin dans cet article.

useState Hook

Naturellement, les composants fonctionnels sont sans état, mais React a introduit le hook useState pour permettre aux développeurs d'ajouter des variables d'état aux composants qui en ont besoin.

Ce hook est appelé au niveau supérieur de votre composant avec une valeur d'état initiale transmise, et il renvoie un tableau de la valeur actuelle et une fonction de définition. Voici un exemple de code montrant comment vous pouvez l'utiliser :

import { useState} from 'react';

function Counter() {
  const [count, setCount] = useState(0);

  return (
    dc6dce4a544fdca2df29d5ac0ea9906b
      e388a4556c0f65e1904146cc1a846beeYou clicked {count} times94b3e26ee717c64999d7867364b1b4a3
      5ddc0978355752d4bf828563dc007a14 setCount(count + 1)}>
        Click me
      65281c5ac262bf6d81768915a4a77ac0
    16b28748ea4df4d9c2150843fecfba68
  );
}

Explication

  • Le décompte initial commence à 0
  • La fonction set count est appelée chaque fois que vous cliquez sur le bouton, mettant à jour la variable count avec la valeur la plus actuelle à tout moment.

Quand utiliser le hook useState

Le hook useState est idéal pour gérer l'état de vos composants lorsque :

  • Gestion de l'état local : l'état n'est nécessaire que dans un seul composant et n'a pas besoin d'être partagé entre plusieurs composants.
  • Logique d'état simple : la logique d'état est simple, comme le basculement des valeurs, des compteurs, des entrées de formulaire et des conditions simples.
  • Hiérarchie limitée des composants : L'état n'a pas besoin de passer profondément à travers plusieurs couches de composants, ce qui peut conduire à un forage d'accessoires.
  • Projets de petite taille : l'application n'a pas de besoins étendus en matière de gestion d'état qui nécessitent des solutions plus avancées.

Exemples :

  • Managing form input values.
  • Toggling UI elements (e.g., show/hide).
  • Simple counters and trackers.

The useState hook provides a simple and efficient way to handle state for these scenarios, ensuring your components remain manageable and easy to understand.

useReducer Hook

The useReducer hook was introduced by the React team to handle complex state logic or case-sensitive updates. Here are the key parameters you need to keep in mind while using useReducer:

  1. reducer: This is the function where all the state updating code is executed. It takes the current state and an action as arguments and returns a new state.
  2. initialArg: This is the initial state that you declare from the onset.
  3. dispatch: This is the function called in the event handler. It is returned from the useReducer hook and is used to send actions to the reducer.
  4. state: This is the current state value also returned by the useReducer hook.

Here’s a code example of how to use this hook:

import React, { useReducer } from 'react';

const initialState = { count: 0 };

function reducer(state, action) {
  switch (action.type) {
    case 'increment':
      return { count: state.count + 1 };
    case 'decrement':
      return { count: state.count - 1 };
    default:
      throw new Error();
  }
}

function Counter() {
  const [state, dispatch] = useReducer(reducer, initialState);

  return (
    dc6dce4a544fdca2df29d5ac0ea9906b
      e388a4556c0f65e1904146cc1a846beeCount: {state.count}94b3e26ee717c64999d7867364b1b4a3
      5ddc0978355752d4bf828563dc007a14 dispatch({ type: 'increment' })}>
        +
      65281c5ac262bf6d81768915a4a77ac0
      5ddc0978355752d4bf828563dc007a14 dispatch({ type: 'decrement' })}>
        -
      65281c5ac262bf6d81768915a4a77ac0
    16b28748ea4df4d9c2150843fecfba68
  );
}

Key Takeaways:

  1. Just like every other hook, useReducer must be called at the top level of the component.
  2. Every time the dispatch function is called, it triggers the reducer, leading to a state update depending on the action. This causes the component to re-render, maintaining the goal of keeping the UI and the current state in sync.
  3. You should only specify the action type in the dispatch function and a payload if need be.

When to Use the useReducer Hook

The useReducer hook is ideal for managing state in your components when:

  • Complex State Logic: The state logic is complex, involves multiple sub-values, or the next state depends on the previous state.
  • State Transition Management: When you need to handle multiple state transitions based on different actions.

Examples of Projects that Require useReducer

  • Complex forms: A multi-step form in a registration process.Each step of the form collects different data, and the state needs to be managed for all steps, with validation and submission logic.

  • Advanced to-do-list: A to-do list application with features like adding, removing, editing, and filtering tasks.

  • E-commerce cart management: An e-commerce site with a shopping cart that handles adding, removing, and updating item quantities.

State Management with Context API

The previously discussed options are great, but they come with a downside: the problem of prop drilling. Prop drilling occurs when a state needs to be passed down through multiple nested components from a parent to a child. This can lead to verbose and hard-to-maintain code, as each intermediary component needs to explicitly pass the state or function down the tree.Global state, which is the state needed by multiple components, becomes particularly challenging to manage with prop drilling.

To solve this problem, React introduced the Context API, which is used for managing global state. The Context API allows you to create a context object that can be accessed by any component within its provider, eliminating the need to pass props through intermediate components.

How to Use the Context API

Here’s a step-by-step guide on how to use it:

  1. Create a Context: First, create a context using the createContext function. This creates an object with a Provider and a Consumer.

    import React, { createContext } from 'react';
    const MyContext = createContext();
    
  2. Provide Context Value: Wrap the components that need access to the context with the Provider component. Pass the value you want to share as a prop to the Provider.

    function App() {
     const [state, setState] = useState("Hello, World!");
     return (
       <MyContext.Provider value={{ state, setState }}>
         <ChildComponent />
       </MyContext.Provider>
     );
    }
    
  3. Consume Context Value: This Use the context value in the child components by using the useContext hook or the Consumer component.

    import React, { useContext } from 'react';
    import MyContext from './path-to-context';
    function ChildComponent() {
     const { state, setState } = useContext(MyContext);
     return (
       <div>
         <p>{state}</p>
         <button onClick={() => setState("Context API is awesome!")}>
           Change Text
         </button>
       </div>
     );
    }
    

Example Usage

Here’s a complete example demonstrating how to use the Context API:

import React, { createContext, useState, useContext } from 'react';

// Create a context
const MyContext = createContext();

function App() {
  const [state, setState] = useState("Hello, World!");

  return (
    43ad9860753b01834247292615a2b05f
      88f9b25aeabe4ed8ddd63b3febe25d20
    8e66e6aff1f0a13ebced51b2c1b5d182
  );
}

function ChildComponent() {
  const { state, setState } = useContext(MyContext);

  return (
    dc6dce4a544fdca2df29d5ac0ea9906b
      e388a4556c0f65e1904146cc1a846bee{state}94b3e26ee717c64999d7867364b1b4a3
      5ddc0978355752d4bf828563dc007a14 setState("Context API is awesome!")}>
        Change Text
      65281c5ac262bf6d81768915a4a77ac0
    16b28748ea4df4d9c2150843fecfba68
  );
}

export default App;

Key Takeaways:

  1. Création du contexte : createContext() est utilisé pour créer l'objet de contexte, qui comprend un fournisseur et un consommateur.
  2. Fournir le contexte : Le composant Provider est utilisé pour transmettre la valeur du contexte actuel à l'arborescence des composants qui en ont besoin.
  3. Consommation du contexte : le hook useContext est utilisé dans un composant fonctionnel pour accéder à la valeur du contexte.

Quand utiliser l'API contextuelle

L'API Context est idéale pour les scénarios dans lesquels vous devez partager un état ou des données sur plusieurs composants sans avoir à transmettre des accessoires à chaque niveau de l'arborescence des composants. Cela est particulièrement utile lorsqu'il s'agit d'un état global ou lorsque l'état doit être accessible par des composants profondément imbriqués. Voici quelques cas spécifiques où l'API Context est bénéfique :

  1. Thème :

    • Exemple : Gestion des thèmes (mode clair ou sombre) sur l'ensemble d'une application.
    • Détails : l'état du thème est partagé entre plusieurs composants, garantissant que l'interface utilisateur reflète de manière cohérente le thème sélectionné.
  2. Authentification de l'utilisateur :

    • Exemple : Gestion de l'état d'authentification des utilisateurs et des informations utilisateur.
    • Détails : L'état d'authentification (connecté/déconnecté) et les données utilisateur (nom d'utilisateur, rôles, etc.) doivent être accessibles par divers composants, tels que les en-têtes, les pages de profil et les itinéraires protégés.
  3. Localisation de la langue :

    • Exemple : Gestion du support multilingue dans une application.
    • Détails : l'état de la langue sélectionnée et les données de traduction doivent être disponibles pour les composants de rendu de texte dans toute l'application.
  4. Gestion d'état complexe pour les formulaires :

    • Exemple : partage des données de formulaire et de l'état de validation entre plusieurs champs et composants de formulaire.
    • Détails : les formulaires qui s'étendent sur plusieurs étapes ou composants peuvent bénéficier d'un état partagé qui suit les valeurs d'entrée et les erreurs de validation.

En comprenant quand et comment utiliser l'API Context, vous pouvez gérer plus efficacement l'état global dans une application React. Cette approche permet d'éviter les pièges du forage d'accessoires, de maintenir votre base de code propre et maintenable et de contribuer à la création d'applications React plus robustes et évolutives.

Bibliothèques tierces pour la gestion de l'État

Les bibliothèques de gestion d'état tierces fournissent des outils et des modèles supplémentaires pour gérer efficacement l'état, en particulier dans les applications complexes. Ces bibliothèques sont souvent dotées de fonctionnalités et d'optimisations avancées qui améliorent les solutions de gestion d'état intégrées fournies par React. Certaines des bibliothèques de gestion d'état tierces les plus populaires incluent Redux, MobX, Recoil et Zustand.

Dans cet article, nous allons aborder Redux. Si vous devez en utiliser d’autres mentionnés, vous pouvez consulter leur documentation ; J'ajouterai des liens à la fin de cet article. Ne vous sentez pas dépassé, la plupart de ces outils sont plutôt adaptés aux débutants. Maintenant, passons directement à Redux !

Gestion d'état avec Redux

Redux est une bibliothèque de gestion d'état tierce qui fournit une solution optimale pour le forage d'accessoires et la gestion globale de l'état en stockant tous les états dans un endroit central appelé le magasin. Cela signifie que tous les composants peuvent accéder à cet état indépendamment, quelle que soit leur position dans l'arborescence des composants.

Cela change la donne, car à mesure que les applications grandissent et qu'il y a plus d'états à gérer, il est essentiel de les résumer en un seul endroit. Cette organisation rend notre code plus propre et le débogage plus facile. Ça a l’air génial, non ?

Gardez à l'esprit que Redux n'est pas spécifiquement limité à React ; c'est une bibliothèque indépendante qui peut être intégrée à d'autres frameworks JavaScript comme Angular, Vue, etc.

Comment utiliser Redux dans React

Avant d'entrer dans le processus étape par étape d'utilisation de Redux, il est important de comprendre les concepts clés qui constituent le fondement de Redux :

  1. Store: The store is the central repository for an application's state. It holds the entire state tree and provides methods to access and update the state.
  2. Reducers: Reducers are pure functions that determine how the state changes in response to actions. They take the current state and an action as arguments and return a new state.
  3. Actions: Actions are plain JavaScript objects that describe what happened in the application. Each action has a type property and may include additional data.
  4. Action Creators: Action creators are functions that create and return action objects. They encapsulate the action creation logic, making the code more manageable.
  5. Dispatch: Dispatch is a function provided by the Redux store that sends actions to the store. It triggers reducers to process the action and update the state.

Understanding these concepts is essential to effectively implementing Redux in your React application.

How to Integrate and Use Redux in Your React Project

In this subsection, you will learn a step-by-step approach to integrating Redux with your React projects. We'll use a simple counter-example to illustrate the process. Here are the steps:

Setting up your Project

  • Create a React app with Vite:

     npm create vite@latest projectName
    
  • Navigate into your project directory:

     cd projectName
    
  • Install Redux Toolkit and React-Redux:

     npm install @reduxjs/toolkit react-redux
    
  1. Creating the Redux Store: Create a new file src/app/store.js and set up the Redux store:

     import { createStore } from 'redux';
     import rootReducer from '../features/counter/counterReducer';
    
     const store = createStore(rootReducer);
    
     export default store;
    
  2. Creating the Reducer: Create a new directory src/features/counter and inside it, create a file counterReducer.js:

     const initialState = {
       value: 0,
     };
    
     function counterReducer(state = initialState, action) {
       switch (action.type) {
         case 'INCREMENT':
           return { ...state, value: state.value + 1 };
         case 'DECREMENT':
           return { ...state, value: state.value - 1 };
         case 'INCREMENT_BY_AMOUNT':
           return { ...state, value: state.value + action.payload };
         default:
           return state;
       }
     }
    
     export default counterReducer;
    
  3. Creating Actions: In the same directory, create a file counterActions.js:

     export const increment = () => ({
       type: 'INCREMENT',
     });
    
     export const decrement = () => ({
       type: 'DECREMENT',
     });
    
     export const incrementByAmount = (amount) => ({
       type: 'INCREMENT_BY_AMOUNT',
       payload: amount,
     });
    
  4. Providing the Store to Your App: Wrap your application with the Redux Provider in src/main.jsx:

     import React from 'react';
     import ReactDOM from 'react-dom';
     import { Provider } from 'react-redux';
     import store from './app/store';
     import App from './App';
     import './index.css';
    
     ReactDOM.render(
       <Provider store={store}>
         <App />
       </Provider>,
       document.getElementById('root')
     );
    
  5. Connecting React Components to Redux: In your src/App.jsx, use the Redux state and dispatch actions:

     import React from 'react';
     import { useSelector, useDispatch } from 'react-redux';
     import { increment, decrement, incrementByAmount } from './features/counter/counterActions';
    
     function App() {
       const count = useSelector((state) => state.value);
       const dispatch = useDispatch();
    
       return (
         <div>
           <p>Count: {count}</p>
           <button onClick={() => dispatch(increment())}>+</button>
           <button onClick={() => dispatch(decrement())}>-</button>
           <button onClick={() => dispatch(incrementByAmount(2))}>+2</button>
         </div>
       );
     }
    
     export default App;
    

This is how to use Redux in your React applications. If you need to know more, you can check the documentation. However, Redux has introduced a more optimized way of writing Redux applications with Redux Toolkit (RTK).

Before RTK, the legacy Redux was the only way to use Redux. Now, we have Redux Toolkit with some optimized features, and that is what we will be covering in the next section.

How to Use Redux Toolkit in React

RTK introduces several key concepts that simplify state management. The major ones you need to know are:

  1. Slices: A slice is a collection of Redux reducer logic and actions for a single feature of your application. It streamlines the process of writing reducers and actions into a single unit.

  2. createSlice: This RTK function helps you create a slice, automatically generating action creators and action types. It reduces boilerplate code significantly.

  3. configureStore: This function simplifies the process of creating a Redux store by providing good defaults, including integration with the Redux DevTools Extension and middleware like redux-thunk.

  4. createAsyncThunk: This function is used for handling asynchronous logic. It generates actions and action creators to manage different stages of an asynchronous operation (e.g., pending, fulfilled, and rejected).

  5. Selectors: Functions that extract and derive pieces of state from the store. RTK encourages using selectors to encapsulate and reuse state logic.

  6. RTK Query: An advanced data fetching and caching tool built into RTK. It simplifies handling server-side data, reducing the need for boilerplate code related to data fetching, caching, and synchronization.

Understanding these concepts is essential for effectively implementing Redux Toolkit in your React application.

How to integrate and use Redux Toolkit in your React project

In this subsection, you'll learn a step-by-step approach to integrating Redux Toolkit with your React projects. We’ll use a simple counter example, similar to the one used in the plain Redux example, to highlight the improvements and optimizations Redux Toolkit offers. Here are the steps:

Setting up your Project

  • Create a React app with Vite:

     npm create vite@latest projectName
    
  • Navigate into your project directory:

     cd projectName
    
  • Install Redux Toolkit and React-Redux:

     npm install @reduxjs/toolkit react-redux
    
  1. Creating a Redux Slice: Create a new file for your slice (e.g., counterSlice.js):

     import { createSlice } from '@reduxjs/toolkit';
    
     const counterSlice = createSlice({
       name: 'counter',
       initialState: { count: 0 },
       reducers: {
         increment: (state) => {
           state.count += 1;
         },
         decrement: (state) => {
           state.count -= 1;
         },
       },
     });
    
     export const { increment, decrement } = counterSlice.actions;
     export default counterSlice.reducer;
    
  2. Configuring the Store: Create a new file for your store (e.g., store.js):

     import { configureStore } from '@reduxjs/toolkit';
     import counterReducer from './counterSlice';
    
     const store = configureStore({
       reducer: {
         counter: counterReducer,
       },
     });
    
     export default store;
    
  3. Providing the Store to Your App: Wrap your app with the Provider component in your main file (e.g., main.js or index.js):

     import React from 'react';
     import ReactDOM from 'react-dom';
     import { Provider } from 'react-redux';
     import store from './store';
     import App from './App';
    
     ReactDOM.render(
       <Provider store={store}>
         <App />
       </Provider>,
       document.getElementById('root')
     );
    
  4. Using Redux State and Actions in Your Components: Use the useSelector and useDispatch hooks in your component (e.g., Counter.js):

     import React from 'react';
     import { useSelector, useDispatch } from 'react-redux';
     import { increment, decrement } from './counterSlice';
    
     function Counter() {
       const count = useSelector((state) => state.counter.count);
       const dispatch = useDispatch();
    
       return (
         <div>
           <p>{count}</p>
           <button onClick={() => dispatch(increment())}>+</button>
           <button onClick={() => dispatch(decrement())}>-</button>
         </div>
       );
     }
    
     export default Counter;
    

Redux Toolkit (RTK) simplifies and optimizes the traditional Redux setup by reducing boilerplate code and integrating essential tools and best practices. While legacy Redux requires manual configuration and verbose code for actions and reducers, RTK offers a more streamlined approach with utility functions like configureStore, createSlice, and createAsyncThunk.

RTK includes built-in middleware, integrates seamlessly with Redux DevTools, and promotes a standard way of writing Redux logic, making state management in React applications more efficient and maintainable. If you need to use Redux, I recommend using the modern Redux Toolkit, as it is now recommended by Redux. You can check the docs to learn more about RTK.

When to Use Redux

Redux is a powerful state management library, but it isn't always necessary for every React application. Here are some scenarios when using Redux might be beneficial:

  1. Complex State Logic:

    • When your application has complex state logic that is difficult to manage with React's built-in hooks like useState and useReducer.
    • Example: An e-commerce application with multiple product filters, user authentication, and a shopping cart.
  2. Global State Management:

    • When you have state that needs to be accessed and updated by many components across different parts of your application.
    • Example: A user authentication system where user data needs to be accessible throughout the application.
  3. Consistent and Predictable State:

    • When you need a predictable state container that helps you debug and test your application more easily.
    • Example: A large-scale application where you need to maintain and track the state transitions clearly.
  4. DevTools Integration:

    • When you want to leverage powerful developer tools like Redux DevTools for tracking state changes and debugging.
    • Example: During development, Redux DevTools can help in understanding how the state changes in response to actions.

Conclusion

I hope by now you have gained more clarity and insights into choosing the right state management tool for your projects. We have covered tools that cater to both small and extremely large projects. With the knowledge gained from this article, you can now make more informed decisions for your projects. See you next time on another insightful topic.

Further reading and learning

  • Redux docs

  • Zustand docs

  • Mobx docs

  • Recoil docs

  • React docs

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