Gestión de estado

Algunas aplicaciones de escaparate exigen una forma específica de gestionar el estado global. Existen muchas bibliotecas de gestión de estado que pueden ayudarle a hacerlo, como Redux y MobX. Salesforce no avala ninguna biblioteca de gestión de estado en particular sobre ninguna otra, y es posible crear una aplicación de PWA Kit sin usar ninguna.

Siempre puede proporcionar información de estado a sus componentes mediante props, pero si desea utilizar las características más avanzadas de React para gestionar el estado, esta guía también cubre otros enfoques.

Uso de props 

La técnica más sencilla para compartir el estado entre componentes es proporcionar dicha información de estado a un componente mediante props. El componente debe ser superior a todos los demás componentes que necesiten acceder a la información de estado. Los documentos de React describen esta técnica en detalle y la llaman levantamiento del estado.

Cómo usar la React Context API 

La Context API de React simplifica el proceso de hacer que la información esté disponible para un gran número de componentes, sin tener que pasar esos datos por props manualmente en cada nivel del árbol de componentes de la aplicación.

Ejemplo de Context de React 

Este es un ejemplo de cómo se puede utilizar la Context API de React con un componente que actúa de contenedor de todos los demás para proporcionarles datos de estado compartidos.

Comience creando un componente llamado GlobalState que tiene dos objetos de contexto:

  1. GlobalStateContext, donde se pueden almacenar datos del estado global.
  2. GlobalDispatchContext, la función dispatch, que arroja una captura actualizada del estado global a través de una función de reducción.

Cada objeto de contexto viene con un” componente que permite a los componentes consumidores suscribirse a los cambios de contexto. Aquí, los objetos de contexto se inicializan con las props initialState y dispatch. Estas props se obtienen al conectar el estado con un reducer, mediante un enlace useReducer. Para obtener más información sobre los enlaces de React, incluido cómo utilizarlos con la Context API, consulte la documentación de referencia oficial de enlaces de React.

A continuación encontrará la forma de definir e inicializar un componente que utilice la Context API para almacenar el estado global en su aplicación de escaparate:

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}

El componente especial AppConfig que está en app/components/_app-config/index.jsx es desde donde se puede iniciar el sistema de gestión de estado. Aquí, props.children contiene todos los componentes de la aplicación, así que aquí es donde se debe agregar el componente GlobalState.

Para obtener el objeto “props” es necesario iniciarlo primero. Utilice el enlace useReducer de React para crear un estado conectado al reductor. La función useReducer toma un objeto initialState y el reducer importado desde el componente GlobalState. A continuación, pasa el estado conectado y una función dispatch para modificar dicho estado.

Por ejemplo:

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}

Ahora puede dar a cualquier componente acceso a sus datos de contexto global, incluida la capacidad de actualizarlos. Importe GlobalStateContext y GlobalDispatchContext del componente GlobalState y proporcione esos objetos de contexto al método useContext().

Por ejemplo:

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}

Cómo utilizar una biblioteca de gestión de estado 

Puede personalizar su aplicación para que use una biblioteca de gestión de estado anulando el componente especial predeterminado AppConfig ubicado en app/components/_app-config/index.jsx.

Ejemplo de Redux 

A continuación encontrará una explicación sobre cómo configurar Redux para su PWA mediante AppConfig dentro. El componente tiene cuatro métodos que debe utilizar:

  1. El método restore es el que se utiliza para crear su tienda Redux con un reductor, un estado inicial y cualquier middleware.
  2. El método freeze le permite congelar su backend de gestión de estado para integrarlo a la página de HTML.
  3. El método extraGetPropsArgs permite arrojar cualquier argumento adicional que quiera incorporar a los métodos getProps de toda la aplicación. En este caso, la tienda Redux puede ser arrojada como un argumento adicional.
  4. El método render permite configurar proveedores de contexto para una biblioteca de gestión de estado. Por ejemplo, se puede usar para encapsular la aplicación en un proveedor Redux.

A continuación encontrará un breve ejemplo que muestra cómo utilizar los métodos de AppConfig para configurar Redux para su aplicación de escaparate. Además de los pasos indicados aquí, para conseguir una solución completa debe crear su tienda con un reductor, un estado inicial y cualquier middleware requerido.

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