React useContext y useReducer simplificado

React
React Native

Los componentes de React pueden almacenar un conjunto de propiedades observables llamadas estados . React puede decidir cómo renderizarse a sí mismo en función de los valores del estado. A veces es importante compartir el estado entre varios componentes pasando el estado a través del árbol de componentes. Cuando el árbol de componentes es demasiado profundo y la aplicación se vuelve más grande, pasar estados usando accesorios a través de todos estos componentes crea un gran lío.

El contexto tiene como objetivo resolver este problema. Almacena todos los estados en un lugar central y comparte los estados entre los componentes sin tener que pasarlos a través del árbol de componentes. React Context API administra el estado de la aplicación en un solo lugar. También hace que el estado sea accesible para todos los componentes.

 

Problema

Para resumir la API de contexto de reacción, crearé una aplicación y le mostraré cómo agregarle contexto.

Crearé una aplicación de lista de tareas pendientes usando solo react. Para el backend no crearé nada. Aprovecharé {JSON} Placeholder.

 

Requisitos

Este tutorial requiere conceptos simples de reacción de los lectores.

 

Configuración del proyecto

Utilice el siguiente comando para crear una aplicación react.js.

npx create-react-app react-context-demo

 

Eliminación de archivos y código innecesarios

Elimine todos los archivos dentro de la src carpeta excepto App.js y index.js.

 

Habilitando React Context

Para habilitar el contexto en la aplicación de reacción, debemos seguir estos pasos:

  • Crear Context
  • Usando Reducer
  • Proporcionar Context
  • Usando el Context

 

Crear contexto

React.js proporciona createContext() hook. Este gancho recibe un argumento como estado inicial y devuelve un contexto. En nuestro ejemplo, creamos un contexto y pasamos el estado inicial que contiene una lista vacía todos.

Cree un archivo dentro de la carpeta SRC con el nombre TodoContext.js y agregue el siguiente código.

import React, { createContext } from 'react';

const initialState = {
	todos: []
};

export const TodosContext = createContext(initialState);

 

Usando Reducer

Reducer es una función recibe dos argumentos state y action y devuelve una llanura JavaScript object. Por lo general, la acción tiene dos variables type y payload.

Cree un archivo llamado carpeta TodoRecuer.js interior src.

import React, { useReducer }  from 'react';

function todosReducer(state, action) {
   switch(action.type) {
      case "FETCH_TODOS":
         return {
            ...state,
            todos: action.payload,
         };
      case "CREATE_TODO":
         return {
            ...state,
            todos: [...state.todos, action.payload],
         };
      default:
         return state;
   }
}

Posteriormente usamos este reducer mediante el hook useReducer.

const [state, dispatch] = useReducer(todoReducer, initialState);

 

Proporcionar contexto

El contexto que se ha creado usando createContext hook, en nuestro ejemplo TodoContext viene con un proveedor de contexto TodoContext.Provider.

  • Tenemos que envolver toda la aplicación con el proveedor. Por esa razón creamos un componente que regresa TodoContext.Provider con hijos.
  • Cree un componente de reacción (una función de JavaScript) dentro del TodoContext.js archivo llamado TodoContextProvider.
// Create Provider
export function TodoContextProvider({ children }) {
  // Use reducer
  const [state, dispatch] = useReducer(todoReducer, initialState);
  
  // Define reducer actions
  function fetchTodos(todos) {
    dispatch({
      type: "FETCH_TODOS",
      payload: todos,
    });
  }
  
  function saveTodo(todo) {
    dispatch({
      type: "SAVE_TODO",
      payload: todo,
    });
  }
  return (
    <TodoContext.Provider
      value={{
        todos: state.todos,
        fetchTodos,
        saveTodo,
      }}
    >
    {children}
    </TodoContext.Provider>
  );
}

En nuestro index.js archivo, envuelva el App componente con TodoContextProvider.

<TodoContextProvider>
  <App />
</TodoContextProvider>

 

Usando el contexto

Hay varias formas de utilizar el contexto dentro de un componente y obtener el estado o actualizarlo.

Un ejemplo de cómo obtener el estado.

import React, { useContext, useEffect } from "react";
import { TodoContext } from "../TodoContext";

export default function ListTodos() {
  const { todos } = useContext(TodoContext);
  return (
    <div className="col-8">
      <table className="table table-hover">
        <thead>
          <tr>
            <th>#</th>
            <th>Title</th>
            <th>Completed</th>
            <th></th>
          </tr>
        </thead>
      <tbody>
      {todos.map((todo, index) => (
        <tr key={index}>
          <td>{index + 1}</td>
          <td>{todo.title}</td>
          <td 
            className={todo.completed
              ? "text-primary"
              : "text-warning"}
          >
            {todo.completed ? "completed" : "uncompleted"}
          </td>
        </tr>
      ))}
      </tbody>
    </table>
  </div>);
}

Un ejemplo de actualización del estado.

import React, { useContext, useState } from 'react';

function CreateTodo() {
   const { createTodo } = useContext(TodoContext);
   const [title, setTitle] = useState('');
   function handleClick() {
      createTodo({
         title
      });
   }
   return (
      <>
         <input
            type="text"
            onChange={e => setTitle(e.target.name)}
         />
         <button onClick={handleClick}>Save</button>
      </>
   );
}

 

Conclusión

React Context es una herramienta poderosa cuando se usa dentro de las aplicaciones React. Simplifica la recuperación del estado o la actualización sin la necesidad de pasar accesorios a la jerarquía de componentes. Más importante aún, el contexto de reacción separa la interfaz de usuario del estado.

Puede encontrar la aplicación este repositorio para obtener un ejemplo más completo.