


Notes complètes sur la boîte à outils Redux pour les développeurs React
? Notes sur la boîte à outils Redux ?
Qu'est-ce que Redux ?
Redux est un conteneur d'état flexible pour les applications JS qui gère l'état de notre application séparément. Il gère l'état de l'application dans un seul magasin, ce qui facilite la gestion d'une logique d'état complexe dans l'ensemble de l'application.
Pourquoi Redux ?
Dans un flux normal, nous devons effectuer un forage d'hélices pour transmettre les états entre les composants. Certains niveaux n’ont pas besoin des États ici, ce qui constitue un fardeau. De plus, améliorer l’état des applications de grande taille n’est pas une solution évolutive car cela nécessite des changements structurels. C'est pourquoi nous avons besoin d'un redux pour gérer les états. Tous les états ici sont conservés en magasin et quel que soit le composant qui en a besoin, ils peuvent simplement s'abonner à ce magasin. Redux garantit une gestion prévisible de l'état, un débogage plus facile et une évolutivité améliorée en appliquant un flux de données unidirectionnel.
Composants de base Redux :
Action : Un objet qui décrit ce qui s'est passé. Il contient généralement un type et une charge utile facultative. (Une commande)
Dispatch : Une fonction utilisée pour envoyer des actions au magasin pour mettre à jour l'état. (Un événement survenant)
Réducteur : Une fonction pure qui prend l'état actuel et une action, puis renvoie un nouvel état. (Fonction qui se déclenche lors de l'envoi d'une action)
Installation : npm i @reduxjs/toolkit réagir-redux
Flux de travail Redux :
Créer une tranche :
Une tranche est un ensemble de logiques et d'actions de réduction Redux pour une seule fonctionnalité. Le rappel de préparation nous permet de personnaliser la charge utile de l'action avant qu'elle n'atteigne le réducteur.
import { createSlice, nanoid } from "@reduxjs/toolkit"; const postSlice = createSlice({ name: "posts", initialState: [], reducers: { addPost: { reducer: (state, action) => { state.push(action.payload); }, prepare: (title, content) => ({ payload: { id: nanoid(), title, content }, }), }, deletePost: (state, action) => { return state.filter((post) => post.id != action.payload); }, }, }); export const { addPost, deletePost } = postSlice.actions; export default postSlice.reducer;
Création de boutique :
import { configureStore } from "@reduxjs/toolkit"; import postReducer from "../features/posts/postSlice"; export const store = configureStore({ reducer: { posts: postReducer }, });
Enveloppement avec le fournisseur :
import { Provider } from "react-redux"; import { store } from "./app/store.jsx"; createRoot(document.getElementById("root")).render( <StrictMode> <Provider store={store}> <App /> </Provider> </StrictMode> );
Utilisation dans le composant :
const PostList = ({ onEdit }) => { const posts = useSelector((state) => state.posts); const dispatch = useDispatch(); return ( <div className="w-full grid grid-cols-1 gap-6 mt-12"> {posts.map((post) => ( <div key={post.id}></div> ))} </div> ); };
Extension du navigateur Redux : Redux DevTools
const store = configureStore({ reducer: rootReducer, devTools: process.env.NODE_ENV !== 'production', });
Opération asynchrone dans Redux (Redux Thunk) :
Dans Redux, les opérations asynchrones (comme les appels d'API) sont gérées à l'aide d'un middleware car Redux ne prend en charge par défaut que les mises à jour d'état synchrones. Les middlewares les plus courants pour gérer les opérations asynchrones sont Redux Thunk, Redux Toolkit (RTK) avec createAsyncThunk et Redux Saga.
Mise en œuvre :
import { createSlice, createAsyncThunk } from '@reduxjs/toolkit'; // Fetch all posts export const fetchPosts = createAsyncThunk('posts/fetchPosts', async () => { const response = await fetch('https://jsonplaceholder.typicode.com/posts'); return response.json(); }); // Initial State const initialState = { posts: [], post: null, loading: false, error: null, }; // Slice const postsSlice = createSlice({ name: 'posts', initialState, reducers: {}, extraReducers: (builder) => { builder // Fetch all posts .addCase(fetchPosts.pending, (state) => { state.loading = true; }) .addCase(fetchPosts.fulfilled, (state, action) => { state.loading = false; state.posts = action.payload; }) .addCase(fetchPosts.rejected, (state, action) => { state.loading = false; state.error = action.error.message; }) }, }); export default postsSlice.reducer;
Cas d'utilisation :
import React, { useEffect } from 'react'; import { useSelector, useDispatch } from 'react-redux'; import { fetchPosts, createPost, updatePost, deletePost } from './postsSlice'; const Posts = () => { const dispatch = useDispatch(); const { posts, loading, error } = useSelector((state) =>state.posts); useEffect(() => { dispatch(fetchPosts()); }, [dispatch]); const handleCreate = () => { dispatch(createPost({ title: 'New Post', body: 'This is a new post' })); }; if (loading) return <p>Loading...</p>; if (error) return <p>Error: {error}</p>; return ( <div> <h1>Posts</h1> <button onClick={handleCreate}>Create Post</button> </div> ); }; export default Posts;
Middleware
Le middleware de Redux intercepte les actions distribuées, permettant la journalisation, le rapport d'incident ou la gestion de la logique asynchrone. Le middleware nous permet de personnaliser le processus d'envoi.
const blogPostMiddleware = (storeAPI) => (next) => (action) => { if (action.type === 'posts/publishPost') { const contentLength = action.payload.content.length; if (contentLength < 50) { console.warn('Post content is too short. Must be at least 50 characters.'); return; } console.log('Publishing post:', action.payload.title); } return next(action); }; const store = configureStore({ reducer: rootReducer, middleware: (getDefaultMiddleware) => getDefaultMiddleware().concat(blogPostMiddleware), });
Sélecteurs
Les sélecteurs aident à accéder à des parties spécifiques de l’État.
export const selectCount = (state) => état.compteur.valeur;
Gestion des erreurs
Gérez efficacement les erreurs grâce à une gestion appropriée de l'état.
import { createSlice, nanoid } from "@reduxjs/toolkit"; const postSlice = createSlice({ name: "posts", initialState: [], reducers: { addPost: { reducer: (state, action) => { state.push(action.payload); }, prepare: (title, content) => ({ payload: { id: nanoid(), title, content }, }), }, deletePost: (state, action) => { return state.filter((post) => post.id != action.payload); }, }, }); export const { addPost, deletePost } = postSlice.actions; export default postSlice.reducer;
Requête RTK (récupération de données simplifiée)
RTK Query simplifie la récupération, la mise en cache et la synchronisation des données. RTK Query met automatiquement en cache les requêtes et évite les récupérations inutiles, améliorant ainsi les performances.
Configuration de la requête RTK
import { configureStore } from "@reduxjs/toolkit"; import postReducer from "../features/posts/postSlice"; export const store = configureStore({ reducer: { posts: postReducer }, });
Utilisation dans les composants
import { Provider } from "react-redux"; import { store } from "./app/store.jsx"; createRoot(document.getElementById("root")).render( <StrictMode> <Provider store={store}> <App /> </Provider> </StrictMode> );
Mises à jour immuables avec Immer
Immer nous permet d'écrire une logique qui "mute" l'état directement tout en gardant les mises à jour immuables sous le capot.
const PostList = ({ onEdit }) => { const posts = useSelector((state) => state.posts); const dispatch = useDispatch(); return ( <div className="w-full grid grid-cols-1 gap-6 mt-12"> {posts.map((post) => ( <div key={post.id}></div> ))} </div> ); };
Mutation vs Immuable
Muter : Modifier les données directement. Par exemple, modifier un objet ou un tableau.
Immuable : Au lieu de modifier directement les données, nous créons une nouvelle copie avec les modifications appliquées, laissant les données d'origine intactes.
Comment fonctionne Immer
Immer nous aide à écrire du code qui donne l'impression que nous sommes en train de muter des données (c'est-à-dire que nous les modifions directement), mais il maintient automatiquement les modifications immuables sous le capot. Ceci est utile pour éviter les bugs courants liés aux structures de données immuables en JavaScript.
Exemple : Sans Immer (mutation) :
const store = configureStore({ reducer: rootReducer, devTools: process.env.NODE_ENV !== 'production', });
Avec Immer (immuabilité) :
import { createSlice, createAsyncThunk } from '@reduxjs/toolkit'; // Fetch all posts export const fetchPosts = createAsyncThunk('posts/fetchPosts', async () => { const response = await fetch('https://jsonplaceholder.typicode.com/posts'); return response.json(); }); // Initial State const initialState = { posts: [], post: null, loading: false, error: null, }; // Slice const postsSlice = createSlice({ name: 'posts', initialState, reducers: {}, extraReducers: (builder) => { builder // Fetch all posts .addCase(fetchPosts.pending, (state) => { state.loading = true; }) .addCase(fetchPosts.fulfilled, (state, action) => { state.loading = false; state.posts = action.payload; }) .addCase(fetchPosts.rejected, (state, action) => { state.loading = false; state.error = action.error.message; }) }, }); export default postsSlice.reducer;
Cela facilite le travail avec Redux (ou toute autre gestion d'état) car nous n'avons pas besoin de cloner et de mettre à jour l'état manuellement ; Immer le fait automatiquement pour nous.
Redux persiste :
Pour conserver l'état Redux lors des actualisations de page, nous pouvons intégrer Redux Persist. Cela stockera votre état Redux dans le stockage local ou le stockage de session et le rechargera lorsque l'application sera actualisée.
Installer :
npm installer redux-persist
Mettre en œuvre :
import React, { useEffect } from 'react'; import { useSelector, useDispatch } from 'react-redux'; import { fetchPosts, createPost, updatePost, deletePost } from './postsSlice'; const Posts = () => { const dispatch = useDispatch(); const { posts, loading, error } = useSelector((state) =>state.posts); useEffect(() => { dispatch(fetchPosts()); }, [dispatch]); const handleCreate = () => { dispatch(createPost({ title: 'New Post', body: 'This is a new post' })); }; if (loading) return <p>Loading...</p>; if (error) return <p>Error: {error}</p>; return ( <div> <h1>Posts</h1> <button onClick={handleCreate}>Create Post</button> </div> ); }; export default Posts;
Enrouler avec Persisit Gate :
const blogPostMiddleware = (storeAPI) => (next) => (action) => { if (action.type === 'posts/publishPost') { const contentLength = action.payload.content.length; if (contentLength < 50) { console.warn('Post content is too short. Must be at least 50 characters.'); return; } console.log('Publishing post:', action.payload.title); } return next(action); }; const store = configureStore({ reducer: rootReducer, middleware: (getDefaultMiddleware) => getDefaultMiddleware().concat(blogPostMiddleware), });
Améliorations facultatives
Utilisez sessionStorage au lieu de localStorage :
Changez le stockage en basé sur la session (s'efface à la fermeture du navigateur) :
initialState: { items: [], status: 'idle', error: null, }, .addCase(fetchData.rejected, (state, action) => { state.status = 'failed'; state.error = action.error.message; });
Persistance sélective :
Ne conserver que des tranches spécifiques de l'État :
import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query/react'; const api = createApi({ reducerPath: 'api', baseQuery: fetchBaseQuery({ baseUrl: 'https://jsonplaceholder.typicode.com' }), endpoints: (builder) => ({ getPosts: builder.query({ query: () => '/posts', }), getPostById: builder.query({ query: (id) => `/posts/${id}`, }), createPost: builder.mutation({ query: (newPost) => ({ url: '/posts', method: 'POST', body: newPost, }), }), updatePost: builder.mutation({ query: ({ id, ...updatedPost }) => ({ url: `/posts/${id}`, method: 'PUT', body: updatedPost, }), }), deletePost: builder.mutation({ query: (id) => ({ url: `/posts/${id}`, method: 'DELETE', }), }), }), }); export const { useGetPostsQuery, useGetPostByIdQuery, useCreatePostMutation, useUpdatePostMutation, useDeletePostMutation, } = api; export default api;
J'ai créé un projet de blog simple avec un design React, Redux et Ant ayant des fonctionnalités CRUD. Vous pouvez le vérifier.
Lien du projet - Application de blog Redux
? Maîtrisez Redux Toolkit et améliorez vos applications React !
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!

Outils d'IA chauds

Undresser.AI Undress
Application basée sur l'IA pour créer des photos de nu réalistes

AI Clothes Remover
Outil d'IA en ligne pour supprimer les vêtements des photos.

Undress AI Tool
Images de déshabillage gratuites

Clothoff.io
Dissolvant de vêtements AI

Video Face Swap
Échangez les visages dans n'importe quelle vidéo sans effort grâce à notre outil d'échange de visage AI entièrement gratuit !

Article chaud

Outils chauds

Bloc-notes++7.3.1
Éditeur de code facile à utiliser et gratuit

SublimeText3 version chinoise
Version chinoise, très simple à utiliser

Envoyer Studio 13.0.1
Puissant environnement de développement intégré PHP

Dreamweaver CS6
Outils de développement Web visuel

SublimeText3 version Mac
Logiciel d'édition de code au niveau de Dieu (SublimeText3)

Sujets chauds











Python convient plus aux débutants, avec une courbe d'apprentissage en douceur et une syntaxe concise; JavaScript convient au développement frontal, avec une courbe d'apprentissage abrupte et une syntaxe flexible. 1. La syntaxe Python est intuitive et adaptée à la science des données et au développement back-end. 2. JavaScript est flexible et largement utilisé dans la programmation frontale et côté serveur.

Les principales utilisations de JavaScript dans le développement Web incluent l'interaction client, la vérification du formulaire et la communication asynchrone. 1) Mise à jour du contenu dynamique et interaction utilisateur via les opérations DOM; 2) La vérification du client est effectuée avant que l'utilisateur ne soumette les données pour améliorer l'expérience utilisateur; 3) La communication de rafraîchissement avec le serveur est réalisée via la technologie AJAX.

L'application de JavaScript dans le monde réel comprend un développement frontal et back-end. 1) Afficher les applications frontales en créant une application de liste TODO, impliquant les opérations DOM et le traitement des événements. 2) Construisez RestulAPI via Node.js et Express pour démontrer les applications back-end.

Comprendre le fonctionnement du moteur JavaScript en interne est important pour les développeurs car il aide à écrire du code plus efficace et à comprendre les goulots d'étranglement des performances et les stratégies d'optimisation. 1) Le flux de travail du moteur comprend trois étapes: analyse, compilation et exécution; 2) Pendant le processus d'exécution, le moteur effectuera une optimisation dynamique, comme le cache en ligne et les classes cachées; 3) Les meilleures pratiques comprennent l'évitement des variables globales, l'optimisation des boucles, l'utilisation de const et de locations et d'éviter une utilisation excessive des fermetures.

Python et JavaScript ont leurs propres avantages et inconvénients en termes de communauté, de bibliothèques et de ressources. 1) La communauté Python est amicale et adaptée aux débutants, mais les ressources de développement frontal ne sont pas aussi riches que JavaScript. 2) Python est puissant dans les bibliothèques de science des données et d'apprentissage automatique, tandis que JavaScript est meilleur dans les bibliothèques et les cadres de développement frontaux. 3) Les deux ont des ressources d'apprentissage riches, mais Python convient pour commencer par des documents officiels, tandis que JavaScript est meilleur avec MDNWEBDOCS. Le choix doit être basé sur les besoins du projet et les intérêts personnels.

Les choix de Python et JavaScript dans les environnements de développement sont importants. 1) L'environnement de développement de Python comprend Pycharm, Jupyternotebook et Anaconda, qui conviennent à la science des données et au prototypage rapide. 2) L'environnement de développement de JavaScript comprend Node.js, VScode et WebPack, qui conviennent au développement frontal et back-end. Le choix des bons outils en fonction des besoins du projet peut améliorer l'efficacité du développement et le taux de réussite du projet.

C et C jouent un rôle essentiel dans le moteur JavaScript, principalement utilisé pour implémenter des interprètes et des compilateurs JIT. 1) C est utilisé pour analyser le code source JavaScript et générer une arborescence de syntaxe abstraite. 2) C est responsable de la génération et de l'exécution de bytecode. 3) C met en œuvre le compilateur JIT, optimise et compile le code de point chaud à l'exécution et améliore considérablement l'efficacité d'exécution de JavaScript.

Python est plus adapté à la science et à l'automatisation des données, tandis que JavaScript est plus adapté au développement frontal et complet. 1. Python fonctionne bien dans la science des données et l'apprentissage automatique, en utilisant des bibliothèques telles que Numpy et Pandas pour le traitement et la modélisation des données. 2. Python est concis et efficace dans l'automatisation et les scripts. 3. JavaScript est indispensable dans le développement frontal et est utilisé pour créer des pages Web dynamiques et des applications à une seule page. 4. JavaScript joue un rôle dans le développement back-end via Node.js et prend en charge le développement complet de la pile.
