Gestion des états

Certaines applications de boutique en ligne exigent un moyen de gérer l’état global. Il existe de nombreuses bibliothèques de gestion d’état qui vous aident pour cela, comme Redux et MobX. Salesforce ne recommande pas une bibliothèque de gestion d’état particulière plutôt qu’une autre. Vous pouvez d’ailleurs créer une application PWA Kit sans en utiliser.

Vous pouvez toujours fournir des informations d’état à vos composants via les props, mais si vous souhaitez utiliser les fonctionnalités plus avancées de React pour gérer l’état, ce guide couvre également d’autres approches.

Utilisation des props 

La technique la plus simple pour partager l’état entre les composants consiste à fournir ces informations d’état par le biais de props à un composant. Ce composant doit être le parent de tous les composants qui ont besoin d’accéder aux données d’état. Les documentations de React décrivent cette technique en détail et l’appellent lifting state up, soit une remontée de l’état dans la hiérarchie.

Utilisation de l'API React Context 

L’API Context de React simplifie le processus de mise à disposition de données à un grand nombre de composants, sans avoir à transmettre manuellement ces données grâce à des props à chaque niveau de l’arborescence des composants de votre app.

Exemple de React Context 

Voici un exemple d’utilisation de l’API React Context avec un composant qui agit comme une enveloppe (wrapper) autour de tous vos composants afin de leur fournir des données d’état partagées.

Commencez par créer un composant appelé GlobalState possédant deux objets de contexte :

  1. GlobalStateContext : où vous pouvez stocker les données d’état global.
  2. GlobalDispatchContext : votre fonction dispatch, qui renvoie un instantané actualisé de l’état global par le biais d’une fonction reducer.

Chaque objet de contexte est livré avec uncomposant ” qui permet aux composants consommateurs de s’abonner aux changements de contexte. Ici, les objets de contexte sont initialisés avec les props initialState et dispatch. Vous recevez ces props lorsque vous connectez votre état avec un reducer, à l’aide du hook useReducer. Pour en savoir plus sur les hooks React, notamment sur leur utilisation avec l’API Context, consultez la documentation de référence officielle sur les hooks React.

Voici comment définir et initialiser un composant qui utilise l’API Context pour stocker l’état global de votre application de boutique en ligne :

1// app/components/_app-config/index.jsx
2
3import {createContext, useContext} from 'react'
4
5export const GlobalContext = createContext()
6export const useGlobalState = () => useContext(GlobalContext)
7
8const AppConfig = (props) => {
9    const [globalState, setGlobalState] = useState({
10        customer: {name: 'Samantha', registered: true},
11    })
12
13    return (
14        <GlobalContext.Provider value={(globalState, setGlobalState)}>
15            {props.children}
16        </GlobalContext.Provider>
17    )
18}
19
20// app/pages/page/index.jsx
21
22import React, {useContext} from 'react'
23import {useGlobalState} from 'components/_app-config'
24
25export const Page = () => {
26    const {customer, setGlobalState} = useGlobalState()
27
28    // Use setGlobalState to change the global state.
29
30    return <div>{customer.name}</div>
31}

Le composant spécial AppConfig situé dans app/components/_app-config/index.jsx vous permet d’initialiser votre système de gestion des états. Ici, props.children contient tous les composants de votre application ; c’est donc là que vous voulez ajouter votre composant GlobalState.

Pour récupérer l’objet props, vous devez d’abord l’initialiser. Utilisez le hook useReducer de React pour créer un état connecté à votre reducer. La fonction useReducer prend un objet initialState et le reducer importé du composant GlobalState. Ensuite, on passe l’état connecté et une fonction dispatch pour modifier cet état.

Exemple :

1// <PROJECT_DIR>/app/components/_app-config/index.jsx
2
3// Replace your existing React imports
4import React, { useState }, { useReducer }, from "react"
5
6// Import GlobalState component defined in previous example
7import GlobalState, { reducer } from "../global-state"
8
9const initialState = {
10  cart: null
11}
12
13// Combine this with your existing AppConfig component code
14function AppConfig(props) {
15  const [state, dispatch] = useReducer(reducer, initialState);
16
17  return (
18    <GlobalState initialState={state} dispatch={dispatch}>
19      {props.children}
20    </GlobalState>
21  )
22}

Vous pouvez désormais donner à n’importe quel composant l’accès à vos données de contexte global, ainsi que la possibilité de les mettre à jour. Importez GlobalStateContext et GlobalDispatchContext à partir de votre composant GlobalState et fournissez ces objets de contexte à la méthode useContext().

Exemple :

1import React, {useContext} from 'react'
2import {GlobalStateContext, GlobalDispatchContext, SET_CART_ITEMS} from 'app/components/global-state'
3
4function ExamplePage() {
5    const globalState = useContext(GlobalStateContext)
6    const dispatch = useContext(GlobalDispatchContext)
7
8    // Use this where you want to update the cart data in your global state
9    dispatch({type: SET_CART_ITEMS, payload: cartItems})
10
11    return ( /* render something */ )
12}

Utilisation d'une bibliothèque de gestion d'état 

Vous pouvez personnaliser votre application afin d’utiliser une bibliothèque de gestion d’état en remplaçant le composant spécial AppConfig par défaut qui se situe dans app/components/_app-config/index.jsx.

Exemple de Redux 

Voici comment configurer Redux pour votre PWA via l’AppConfig interne. Le composant dispose de quatre méthodes que vous devez utiliser :

  1. La méthode restore est celle où vous créez votre store Redux avec un reducer, un état initial et un middleware de votre choix.
  2. La méthode freeze vous permet de figer votre backend de gestion d’état pour l’intégrer dans la page HTML.
  3. La méthode extraGetPropsArgs vous permet de renvoyer tous les arguments supplémentaires que vous souhaitez injecter dans les méthodes getProps dans toute l’application. Dans ce cas, nous pouvons retourner le store Redux comme argument supplémentaire.
  4. La méthode render permet de configurer des fournisseurs de contexte pour une bibliothèque de gestion des états. Par exemple, vous pouvez l’utiliser pour envelopper l’application dans un fournisseur Redux.

Voici un bref exemple d’utilisation des méthodes d’AppConfig pour configurer Redux pour votre application de boutique. Outre les étapes présentées ici, une solution complète exige que vous créiez votre store avec un reducer, un état initial et tout middleware requis.

1// <PROJECT_DIR>/app/components/_app-config/index.jsx
2
3// Combine these imports with your existing imports to include Redux
4imports import React, { useState }, { useReducer }, from "react"
5import PropTypes from "prop-types"
6import { createStore } from "redux"
7import { Provider } from "react-redux"
8
9/**
10 * Combine this code with your existing AppConfig code to use Redux by injecting store object and dispatch function into all getProps() functions.
11 */
12
13class AppConfig extends React.Component {
14  static restore(locals, frozen = {}) {
15    // create your store with a reducer, initial state, and any middleware.
16    const initialState = isServerSide ? {} : frozen
17    locals.store = createStore(reducer, initialState, middlewares)
18  }
19  static freeze(locals) {
20    return locals.store.getState()
21  }
22  static extraGetPropsArgs(locals) {
23    return {
24      store: locals.store,
25      dispatch: locals.store.dispatch
26    }
27  }
28
29  /**
30   * The render function will wrap the app in a Redux provider.
31   */
32  render() {
33    const { children, locals } = this.props
34    return <Provider store={locals.store}>{children}</Provider>
35  }
36}
37
38AppConfig.propTypes = {
39  children: PropTypes.node,
40  locals: PropTypes.object
41}
42
43export default AppConfig