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
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.
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.
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.
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.
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 :
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.
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 hook useState est idéal pour gérer l'état de vos composants lorsque :
Exemples :
The useState hook provides a simple and efficient way to handle state for these scenarios, ensuring your components remain manageable and easy to understand.
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:
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:
The useReducer hook is ideal for managing state in your components when:
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.
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.
Here’s a step-by-step guide on how to use it:
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();
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> ); }
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:
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 :
Thème :
Authentification de l'utilisateur :
Localisation de la langue :
Gestion d'état complexe pour les formulaires :
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.
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 !
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.
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 :
Understanding these concepts is essential to effectively implementing Redux in your React application.
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
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;
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;
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, });
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') );
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.
RTK introduces several key concepts that simplify state management. The major ones you need to know are:
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.
createSlice: This RTK function helps you create a slice, automatically generating action creators and action types. It reduces boilerplate code significantly.
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.
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).
Selectors: Functions that extract and derive pieces of state from the store. RTK encourages using selectors to encapsulate and reuse state logic.
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.
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
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;
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;
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') );
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.
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:
Complex State Logic:
Global State Management:
Consistent and Predictable State:
DevTools Integration:
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.
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!