Apprenez à utiliser Redux

Redux est un gestionnaire d'état généralement utilisé avec React, mais il n'est pas lié à cette bibliothèque. Apprenez Redux en lisant ce guide simple et facile à suivre

Pourquoi vous avez besoin de Redux

Redux est un gestionnaire d'état généralement utilisé avec React, mais il n'est pas lié à cette bibliothèque - il peut également être utilisé avec d'autres technologies, mais nous nous en tiendrons à React pour l'explication.

React a sa propre façon de gérer l'état, comme vous pouvez le lire sur leGuide du débutant React, où je présente comment vous pouvez gérer State dans React.

Le déplacement de l'état vers le haut dans l'arborescence fonctionne dans des cas simples, mais dans une application complexe, vous pouvez constater que vous déplacez presque tout l'état vers le haut, puis vers le bas à l'aide d'accessoires.

React dans la version 16.3.0 a introduit leAPI de contexte, ce qui rend Redux redondant pour le cas d'utilisation d'accès à l'état à partir de différentes parties de votre application, envisagez donc d'utiliser l'API de contexte au lieu de Redux, à moins que vous n'ayez besoin d'une fonctionnalité spécifique fournie par Redux.

Redux est un moyen de gérer un état d'application et de le déplacer vers unmagasin global externe.

Il y a quelques concepts à comprendre, mais une fois que vous le faites, Redux est une approche très simple du problème.

Redux est très populaire avec les applications React, mais il n'est en aucun cas unique à React: il existe des liaisons pour presque tous les frameworks populaires. Cela dit, je vais faire quelques exemples en utilisant React car c'est son cas d'utilisation principal.

Quand devriez-vous utiliser Redux?

Redux est idéal pour les applications moyennes à grandes, et vous ne devez l'utiliser que lorsque vous avez des difficultés à gérer l'état avec la gestion d'état par défaut de React ou de l'autre bibliothèque que vous utilisez.

Les applications simples ne devraient pas du tout en avoir besoin (et il n'y a rien de mal avec les applications simples).

Arbre d'état immuable

Dans Redux, l'état complet de l'application est représenté parune JavaScriptobjet, appeléÉtatouArborescence des états.

Nous l'appelonsArbre d'état immuablecar il est en lecture seule: il ne peut pas être modifié directement.

Il ne peut être modifié qu'en envoyant unaction.

Actions

Uneactionestun objet JavaScript qui décrit un changement de manière minimale(avec juste les informations nécessaires):

{
  type: 'CLICKED_SIDEBAR'
}

// e.g. with more data { type: ‘SELECTED_USER’, userId: 232 }

La seule exigence d'un objet d'action est d'avoir untypepropriété, dont la valeur est généralement une chaîne.

Les types d'actions doivent être des constantes

Dans une application simple, un type d'action peut être défini sous forme de chaîne.

Lorsque l'application se développe, il est préférable d'utiliser des constantes:

const ADD_ITEM = 'ADD_ITEM'
const action = { type: ADD_ITEM, title: 'Third item' }

et séparer les actions dans leurs propres fichiers et les importer

import { ADD_ITEM, REMOVE_ITEM } from './actions'

Créateurs d'action

Créateurs d'actionssont des fonctions qui créent des actions.

function addItem(t) {
  return {
    type: ADD_ITEM,
    title: t
  }
}

Vous exécutez généralement des créateurs d'action en combinaison avec le déclenchement du répartiteur:

dispatch(addItem('Milk'))

ou en définissant une fonction de répartiteur d'action:

const dispatchAddItem = i => dispatch(addItem(i))
dispatchAddItem('Milk')

Réducteurs

Lorsqu'une action est déclenchée, quelque chose doit se produire, l'état de l'application doit changer.

C'est le travail deréducteurs.

Qu'est-ce qu'un réducteur

UNEréducteurest unfonction purequi calcule l'arborescence d'états suivante en fonction de l'arborescence d'états précédente et de l'action distribuée.

;(currentState, action) => newState

Une fonction pure prend une entrée et renvoie une sortie sans changer l'entrée ou quoi que ce soit d'autre. Ainsi, un réducteur renvoie un état complètement nouveau qui remplace le précédent.

Ce qu'un réducteur ne devrait pas faire

Un réducteur doit être une fonction pure, il doit donc:

  • ne mute jamais ses arguments
  • ne jamais muter l'état, mais en créer un nouveau avecObject.assign({}, ...)
  • ne jamais générer d'effets secondaires (aucun appel d'API ne change quoi que ce soit)
  • ne jamais appeler des fonctions non pures, des fonctions qui modifient leur sortie en fonction de facteurs autres que leur entrée (par exempleDate.now()ouMath.random())

Il n'y a pas de renforcement, mais vous devez vous en tenir aux règles.

Réducteurs multiples

Étant donné que l'état d'une application complexe peut être très large, il n'y a pas un seul réducteur, mais de nombreux réducteurs pour tout type d'action.

Une simulation d'un réducteur

À la base, Redux peut être simplifié avec ce modèle simple:

L'état

{
  list: [
    { title: "First item" },
    { title: "Second item" },
  ],
  title: 'Groceries list'
}

Une liste d'actions

{ type: 'ADD_ITEM', title: 'Third item' }
{ type: 'REMOVE_ITEM', index: 1 }
{ type: 'CHANGE_LIST_TITLE', title: 'Road trip list' }

Un réducteur pour chaque partie de l'État

const title = (state = '', action) => {
    if (action.type === 'CHANGE_LIST_TITLE') {
      return action.title
    } else {
      return state
    }
}

const list = (state = [], action) => { switch (action.type) { case ‘ADD_ITEM’: return state.concat([{ title: action.title }]) case ‘REMOVE_ITEM’: return state.filter(item => action.index !== item.index) default: return state } }

Un réducteur pour tout l'État

const listManager = (state = {}, action) => {
  return {
    title: title(state.title, action),
    list: list(state.list, action)
  }
}

Le magasin

LeMagasinest un objet qui:

  • détient l'étatde l'application
  • expose l'étatviagetState()
  • permettez nous demettre à jour l'étatviadispatch()
  • nous permet de (dés) enregistrer unécouteur de changement d'étatutilisantsubscribe()

Un magasin estuniquedans l'appli.

Voici comment un magasin pour l'application listManager est créé:

import { createStore } from 'redux'
import listManager from './reducers'
let store = createStore(listManager)

Puis-je initialiser le magasin avec des données côté serveur?

Sûr,il suffit de passer un état de départ:

let store = createStore(listManager, preexistingState)

Obtenir l'état

store.getState()

Mettre à jour l'état

store.dispatch(addItem('Something'))

Écoutez les changements d'état

const unsubscribe = store.subscribe(() =>
  const newState = store.getState()
)

unsubscribe()

Flux de données

Le flux de données dans Redux est toujoursunidirectionnel.

Tu appellesdispatch()sur le magasin, en passant une action.

Le magasin s'occupe de transmettre l'action au réducteur, générant l'état suivant.

Le magasin met à jour l'état et alerte tous les écouteurs.

Téléchargez mon gratuitManuel React


Plus de tutoriels de réaction: