Gestión de estados en Gatsby mediante el gancho wrapRootElement

Índice
  1. Instalación
  2. Envolviendo con Proveedor
  3. Estilo
  4. Aplicación de temas
  5. Conclusión

Dado que Gatsby se encarga de nuestras rutas, no nos queda ningún lugar donde encapsular nuestra aplicación con una tienda o proveedor de Redux. En este artículo, aprenderemos un truco inteligente para solucionar este problema.

Para simplificar, todos los ejemplos utilizarán la API de contexto de React para la gestión de estados y ahorrarán tiempo en la configuración de código repetitivo, pero todo sigue siendo aplicable a otros métodos de gestión de estados. Si necesitas repasar cómo trabajar con proveedores, puedes consultar esta introducción al gancho useContext.

Instalación

Prefiero empezar con un tema muy básico, pero al final solo necesitamos algo con dos páginas para que podamos ver que nuestro estado se está aplicando globalmente. Como trabajaremos con algunos estilos, agregaré soporte para Sass con node-sassy gatsby-plugin-sass, porque no soy un animal.

$ gatsby new stateful-gatsby https://github.com/gatsbyjs/gatsby-starter-defaultCopyInstall$ cd stateful-gatsby$ yarn add node-sass gatsby-plugin-sass -D

Envolviendo con Proveedor

El primer paso es configurar nuestro proveedor de contexto con un isDarkestado simple y un método para revertir su estado actual. Tomaremos lo que se pase como propiedades y lo incluiremos en nuestro nuevo myContext.Provider.

proveedor.js

import React, { useState } from 'react';export const myContext = React.createContext();const Provider = props = {  const [isDark, setTheme] = useState(false);  return (    myContext.Provider value={{      isDark,      changeTheme: () = setTheme(!isDark)    }}      {props.children}    /myContext.Provider  )};

Justo debajo, exportaremos una función que envolverá todo lo que se le pase en nuestro nuevo proveedor.

export default ({ element }) = (  Provider    {element}  /Provider);

Ahora que tenemos una forma de administrar nuestro estado, Gatsby nos ofrece un pequeño y elegante gancho llamado wrapRootElement, que puedes consultar en la documentación. Este gancho toma la mayor parte de nuestro sitio y lo pasa como propiedades a una función que le damos, como la que acabamos de exportar desde Provider.js, lo que nos da el pequeño espacio perfecto para incluir todo dentro.

Tanto gatsby-browser.jsy gatsby-ssr.jstienen acceso a este gancho y se recomienda envolver ambos con nuestro proveedor, por eso definimos la función envolvente en provider.js.

import Provider from './provider';export const wrapRootElement = Provider;

Estilo

Aquí están nuestros estilos de temas simples:

origen/global.sass

.colorTheme     height: 100vh    transition: .3s ease-in-out.darkTheme     @extend .colorTheme    background-color: #1A202C    color: #fff    a        color: yellow.lightTheme     @extend .colorTheme    background-color: #fff    color: #000

Aplicación de temas

Lo único que debemos hacer para acceder a nuestro estado es envolver cada componente en un myContext.Consumery acceder a nuestro estado global en contextReact.Fragment es solo para permitirnos agregar más de un elemento.

Para nuestro color de fondo podemos establecer nuestra clase condicionalmente a nuestro estado, si tuviera más de un tema podría establecer el tema del proveedor como una cadena con nuestro nombre de clase.

diseño.js

import { myContext } from '../../provider';import '../global.sass'; return (    myContext.Consumer      {context = (        React.Fragment          div className={context.isDark ? 'darkTheme' : 'lightTheme'}            {/* ... */}          /div        /React.Fragment      )}    /myContext.Consumer  )

También tenemos acceso a setThemeporque se lo pasamos al changeThememétodo. Agreguemos un botón a reverse isDark.

src/paginas/index.js

import { myContext } from '../../provider';const IndexPage = () = (  Layout    myContext.Consumer      {context = (        React.Fragment          SEO /          h1{context.isDark ? "Dark Theme" : "Light Theme"}/h1          button onClick={() = context.changeTheme()}{context.isDark ? "Light" : "Dark"}/button          Link to="/page-2/"Go to page 2/Link        /React.Fragment      )}    /myContext.Consumer  /Layout);

Ahora bien, si agrega esencialmente la misma configuración, page-2.jsdebería poder cambiar el estado y moverse entre ellos sin que el estado se desvanezca entre ellos.

página-2.js

import { myContext } from '../../provider';const SecondPage = () = (  Layout    myContext.Consumer      {context = (        React.Fragment          SEO /          h1{context.isDark ? "Dark Theme" : "Light Theme"}/h1          pWelcome to page 2/p          button onClick={() = context.changeTheme()}{context.isDark ? "Light" : "Dark"}/button          Link to="/"Go back to the homepage/Link        /React.Fragment      )}    /myContext.Consumer  /Layout);

¡Hurra! Es así de simple: 3 pequeños cambios de archivo y empaquetar todo en un consumidor y listo.

Conclusión

Para mí, esta no era una forma muy obvia de hacer las cosas, así que espero que esto haya sido útil para comprender cómo usar el wrapRootElementgancho a su favor.

Para mayor comodidad, he creado un repositorio con esta configuración como inicio, que puedes consultar aquí.

SUSCRÍBETE A NUESTRO BOLETÍN 
No te pierdas de nuestro contenido ni de ninguna de nuestras guías para que puedas avanzar en los juegos que más te gustan.

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Subir

Este sitio web utiliza cookies para mejorar tu experiencia mientras navegas por él. Este sitio web utiliza cookies para mejorar tu experiencia de usuario. Al continuar navegando, aceptas su uso. Mas informacion