Qué es y cuándo usar useReducer en React

useReducer Hook React

React es una biblioteca de JavaScript que nos permite crear interfaces de usuario interactivas de manera eficiente. Para manejar el estado en los componentes de React, a menudo utilizamos useState, pero cuando el manejo del estado se vuelve más complejo, React nos ofrece un hook más potente: useReducer.

Este hook está inspirado en el patrón de diseño de un «reductor» o reducer que solemos ver en bibliotecas como Redux. En este artículo vamos a profundizar sobre sus características y responderemos la pregunta sobre cuándo es conveniente usarlo.

¿Qué es useReducer?

Para comenzar, hay que explicar que useReducer es un hook que se utiliza para manejar estados complejos o cuando las transiciones entre estados dependen de múltiples factores. Es una alternativa más estructurada a useState, especialmente útil cuando:

  1. El estado tiene múltiples valores.
  2. Las actualizaciones del estado dependen de acciones complejas o están relacionadas entre sí.
  3. Necesitamos mantener la lógica de manejo del estado en una función separada.

En términos más simples, useReducer se basa en la idea de un reductor: una función que recibe un estado y una acción, y devuelve un nuevo estado basado en esa acción.

Sintaxis de useReducer

La sintaxis básica de useReducer es la siguiente:

const [state, dispatch] = useReducer(reducer, initialState);
  • reducer: es una función que determina cómo cambiará el estado en función de la acción recibida.
  • initialState: el estado inicial con el que comenzamos.
  • state: es el estado actual.
  • dispatch: es la función que utilizamos para despachar (enviar) acciones al reductor.

Ejemplo con código explicado

Supongamos que queremos manejar el estado de un contador, pero en lugar de usar useState, utilizamos useReducer para tener un mayor control sobre las diferentes acciones que pueden afectar al contador:

import React, { useReducer } from 'react';

// Función reductora
const reducer = (state, action) => {
  switch (action.type) {
    case 'increment':
      return { count: state.count + 1 };
    case 'decrement':
      return { count: state.count - 1 };
    case 'reset':
      return { count: 0 };
    default:
      return state;
  }
};

function Counter() {
  const initialState = { count: 0 };
  const [state, dispatch] = useReducer(reducer, initialState);

  return (
    <div>
      <p>Contador: {state.count}</p>
      <button onClick={() => dispatch({ type: 'increment' })}>Incrementar</button>
      <button onClick={() => dispatch({ type: 'decrement' })}>Decrementar</button>
      <button onClick={() => dispatch({ type: 'reset' })}>Resetear</button>
    </div>
  );
}

export default Counter;

Aquí la función reducer recibe el estado actual y una acción. Dependiendo del tipo de acción (increment, decrement o reset), devuelve un nuevo estado. Usamos dispatch para enviar las acciones, y esto actualiza el estado en consecuencia.

¿Cuándo usar useReducer en lugar de useState?

Aunque useState es suficiente para manejar estados simples, hay varios casos en los que useReducer es más adecuado:

  1. Estados complejos: Si el estado incluye múltiples propiedades o si necesitas realizar actualizaciones basadas en varias acciones, useReducer te ayuda a mantener la lógica centralizada y organizada. Ejemplo: Si tienes un formulario con múltiples campos y deseas manejar cada cambio en función de diferentes acciones:
   const formReducer = (state, action) => {
     switch (action.type) {
       case 'updateField':
         return { ...state, [action.field]: action.value };
       default:
         return state;
     }
   };
  1. Lógica de actualización dependiente. Si las actualizaciones del estado requieren una lógica condicional o múltiple, useReducer nos permite agrupar esa lógica en un solo lugar, haciéndola más legible y fácil de mantener.
  2. Manejo de acciones. Si tenemos varias acciones que impactan el estado, useReducer organiza mejor estas acciones y sus efectos en lugar de tener múltiples llamadas a setState.
  3. Escalabilidad. Si planeamoss que el componente crezca en complejidad, useReducer ofrece una estructura más fácil de escalar que el uso repetido de useState.

¿Cuándo no usar useReducer?

A continuación analizaremos algunos casos donde puede no ser recomendable emplear useReducer:

  • Estados simples. Si solo necesitamos manejar un estado simple (por ejemplo, un valor booleano o un contador básico), useState sigue siendo más adecuado. useReducer añade una capa de complejidad que no siempre es necesaria.
  • Simplicidad en el código. Si useState te proporciona todo lo que necesitamos y el código sigue siendo claro y mantenible, no es necesario complicarlo con un reductor.

En conclusión

Siempre destaco en mis capacitaciones que useReducer es una herramienta poderosa en React para manejar estados complejos o dependientes de múltiples acciones. Si nos enfrenamos a una lógica complicada de actualización de estado o deseamos una forma más estructurada de manejar varios valores de estado, este hook es la opción perfecta. Sin embargo, para casos simples, useState sigue siendo la opción más sencilla y directa.

Como siempre destaco en mis capacitaciones, en programación siempre resulta importante elegir la herramienta adecuada para cada situación. Espero que esta guía te haya servido como inicio para conocer esta característica de React.

Encontraremos más información sobre useReducer en la guía de referencia de Hooks de React.

Si te interesa saber más de React dejame un comentario o escribime un mensaje.

Más sobre Diseño y desarrollo Web


Acerca de

Autor de los libros: Webmaster Profesional, HTML5: Comprenda el cambio y Apps HTML5 para móviles. Soy especialista en Desarrollo Web. Realizo proyectos basados en Inteligencia Artificial. Colaboré como autor y editor de contenidos para revistas, colecciones y diversos medios impresos y digitales. Brindo capacitaciones, clases de formación y consultorías sobre lenguajes de programación y herramientas para Desarrollo Web y móvil en modalidad online y presencial.

Deja una respuesta

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

*