OpenWebinars

Desarrollo Web

Migrando de Redux a Redux Toolkit: Guía paso a paso

¿Estás cansado de escribir tanto código repetitivo con Redux? Redux Toolkit ofrece una forma más simple y eficiente de gestionar el estado de tus aplicaciones. En esta guía paso a paso aprenderás cómo hacer la transición y mejorar tu flujo de trabajo en el proceso.

Alfredo Barragán

Alfredo Barragán

Experto Full Stack con PHP y JavaScript

Lectura 5 minutos

Publicado el 23 de septiembre de 2024

Compartir

Introducción

Has estado usando Redux durante años, pero con el crecimiento de tus proyectos, te das cuenta de que gestionar el estado se vuelve cada vez más complejo y tedioso.

Entonces, escuchas sobre Redux Toolkit, una versión más optimizada y fácil de usar.

Migrar puede sonar intimidante, pero en esta guía paso a paso te mostraremos cómo hacerlo sin complicaciones, mejorando tu flujo de trabajo y reduciendo el código repetitivo.

Por qué elegir Redux Toolkit

Redux Toolkit (RTK) es una mejora significativa sobre la implementación tradicional de Redux, ya que reduce el código repetitivo (boilerplate) y facilita la configuración. Ofrece herramientas como createSlice y createAsyncThunk para simplificar la creación de acciones y reducers, y utiliza Immer para manejar la inmutabilidad de forma eficiente.

RTK mejora el rendimiento, es más fácil de escalar y mantener, y sigue patrones consistentes que facilitan la colaboración en equipos grandes. Además, cuenta con una documentación completa y el respaldo de una comunidad activa, lo que lo convierte en la opción ideal para proyectos modernos que utilizan Redux.

Si te interesa profundizar más en las ventajas que ofrece Redux Toolkit, te recomendamos leer el post anterior sobre Redux Toolkit: Simplifica la gestión del estado. Ahí exploramos en detalle los beneficios clave y cómo Redux Toolkit puede mejorar tu flujo de trabajo.

Aprende a desarrollar webs optimizadas
Comienza 15 días gratis en OpenWebinars y accede cursos, talleres y laboratorios prácticos de JavaScript, React, Angular, HTML, CSS y más.
Registrarme ahora

Migración de Redux a Redux Toolkit

Migrar de Redux a Redux Toolkit no tiene por qué ser un proceso complicado.

En esta sección, te guiaremos cada paso necesario para realizar esta transición de manera simple y efectiva.

Verificar la configuración de Redux

Antes de comenzar con la migración, es fundamental revisar la configuración actual de Redux en tu proyecto. Asegúrate de que el código esté bien organizado y documentado, y toma nota de todos los reducers, actions, y thunks que ya tienes implementados.

Esto te dará un punto de referencia para comenzar la migración y te ayudará a identificar cualquier área que pueda requerir una especial atención durante el proceso.

Instalación de Redux Toolkit

El primer paso concreto en la migración es instalar Redux Toolkit en tu proyecto. Puedes hacerlo utilizando npm o yarn:

npm install @reduxjs/toolkit

O si usas Yarn:

yarn add @reduxjs/toolkit

Esta instalación te proporcionará todas las herramientas necesarias para empezar a refactorizar tu código existente hacia una implementación más moderna y eficiente.

Reconfiguración del store

Uno de los cambios clave al migrar a Redux Toolkit es la reconfiguración del store. En lugar de utilizar createStore de Redux, usarás configureStore de Redux Toolkit. Este método no solo simplifica la configuración, sino que también aplica automáticamente las mejores prácticas, como la inclusión de middleware útil como redux-thunk y herramientas de depuración.

Ejemplo de reconfiguración del store:

import { configureStore } from "@reduxjs/toolkit";
import counterReducer from "./features/counter/counterSlice";

export const store = configureStore({
  reducer: {
    counter: counterReducer,
  },
});

Refactorización de reducers con createSlice

Uno de los mayores beneficios de Redux Toolkit es la función createSlice, que combina la lógica del reducer y las acciones en un solo lugar. Esto reduce significativamente la cantidad de código y hace que la lógica sea más fácil de comprender.

Ejemplo de refactorización reducers:

import { createSlice } from "@reduxjs/toolkit";

export const counterSlice = createSlice({
  name: "counter",
  initialState: { value: 0 },
  reducers: {
    increment: (state) => {
      state.value += 1;
    },
    decrement: (state) => {
      state.value -= 1;
    },
  },
});

export const { increment, decrement } = counterSlice.actions;
export default counterSlice.reducer;

Migración de Thunks a createAsyncThunk

Si tu aplicación utiliza thunks para manejar operaciones asincrónicas, Redux Toolkit ofrece createAsyncThunk, una forma más sencilla y estructurada de definir estas acciones. createAsyncThunk gestiona automáticamente los ciclos de vida de la acción (pendiente, cumplida, rechazada) y actualiza el estado en consecuencia.

Ejemplo de migración thunks:

import { createAsyncThunk } from "@reduxjs/toolkit";

export const fetchUser = createAsyncThunk("users/fetchUser", async (userId) => {
  const response = await fetch(`/api/users/${userId}`);
  return response.json();
});

Actualización de componentes

Después de migrar los reducers y thunks, necesitarás actualizar los componentes que interactúan con el store de Redux. Asegúrate de ajustar las importaciones y adaptarlas a la nueva estructura. Además, revisa el uso de useSelector y useDispatch para asegurarte de que sigan funcionando correctamente con las nuevas configuraciones y slices.

Uso de Codemods

Redux Toolkit proporciona codemods, un conjunto de herramientas automatizadas diseñadas para modificar el código de manera eficiente y segura. Este cojunto de herramientas es especialmente útil durante procesos de migración complejos, como cuando se quiere actualizar un proyecto de Redux que utiliza patrones más antiguos a la sintaxis más moderna y recomendada de Redux Toolkit. Uno de los casos de uso más comunes es la migración de la sintaxis de objeto deprecated a la sintaxis de builder, que es más robusta y flexible. Para facilitar este proceso, puedes utilizar el siguiente comando en la terminal:

npx @reduxjs/rtk-codemods createReducerBuilder ./src

Este comando busca y transforma automáticamente las partes de tu código que todavía utilizan la sintaxis de objeto antigua, actualizándolas a la nueva sintaxis de builder. Esto no solo ahorra tiempo, sino que también minimiza el riesgo de errores manuales durante la migración. Es especialmente beneficioso en proyectos grandes, donde realizar estos cambios manualmente podría ser tedioso y propenso a errores.

Al utilizar codemods, puedes asegurarte de que tu aplicación sigue las mejores prácticas de Redux Toolkit, aprovechando todas sus ventajas, como la reducción del código repetitivo (boilerplate), la simplificación en el manejo de la lógica asíncrona y una experiencia de desarrollo más fluida y eficiente, sin embargo, al tratarse de un proceso automatizado debe prestar especial atención a los cambios que realice en tu código.

Pruebas y ajustes finales

Una vez completada la migración, es imprescindible realizar pruebas exhaustivas para garantizar que todo funcione como se espera. Ejecuta tus pruebas unitarias y de integración para identificar posibles errores o comportamientos inesperados.

Si encuentras problemas, ajusta el código según sea necesario, aprovechando las herramientas de depuración como Redux DevTools para diagnosticar y resolver los problemas.

Para comprobar que Redux Toolkit está funcionando correctamente, puedes escribir pruebas unitarias que verifiquen el comportamiento de los reducers y las acciones generadas por createSlice.

Mejores prácticas para la migración

  • Migración gradual: Si trabajas en una aplicación de un tamaño considerable, considera realizar la migración de forma gradual. Comienza migrando un módulo o slice a la vez, probando y verificando que todo funcione antes de continuar con el siguiente. Esto reducirá el riesgo de introducir errores y facilitará la resolución de problemas si algo no funciona como se espera.

  • Mantenimiento del código: Durante y después de la migración, asegúrate de mantener el código limpio y bien documentado. Aprovecha la estructura modular que ofrece Redux Toolkit para organizar tu código de manera que sea fácil de entender y mantener. Además, actualiza la documentación interna para reflejar cualquier cambio en la arquitectura del estado y las operaciones asincrónicas.

  • Rendimiento optimizado: Redux Toolkit incluye varias optimizaciones de rendimiento, como la inmutabilidad automática del estado con Immer. Sin embargo, siempre es recomendable monitorear el rendimiento después de la migración para asegurarte de que la aplicación siga funcionando de manera eficiente. Además, debes considerar el uso de herramientas de monitoreo de rendimiento y análisis para detectar posibles cuellos de botella.

  • Documentar el proceso de migración: Documenta las razones, los pasos y las decisiones tomadas durante la migración para ayudar a otros desarrolladores a entender los cambios y para facilitar futuras actualizaciones o migraciones.

Plan de Migración a Redux Toolkit

Preparación Inicial

  • Revisión del proyecto actual: Analiza la estructura actual de tu proyecto Redux, identificando los reducers, actions, thunks, y cualquier middleware personalizado que estés utilizando.

  • Instala Redux Toolkit y su dependencia:

  npm install @reduxjs/toolkit react-redux
  • Crea un branch de migración: Crea una rama separada en tu repositorio para realizar la migración, lo que permitirá integrar los cambios sin afectar el código de producción:
 git checkout -b migration-to-redux-toolkit

Migración de reducers

  • Identifica un reducer para migrar: Selecciona un reducer existente en tu proyecto. Como ejemplo, migraremos un reducer que gestiona el estado de autenticación.
// authReducer.js (Antes de la migración)
const initialState = {
  isAuthenticated: false,
  user: null,
};

function authReducer(state = initialState, action) {
  switch (action.type) {
    case "LOGIN_SUCCESS":
      return {
        ...state,
        isAuthenticated: true,
        user: action.payload,
      };
    case "LOGOUT":
      return initialState;
    default:
      return state;
  }
}

export default authReducer;
  • Migra el reducer con redux toolkit: Utiliza createSlice para migrar el reducer:
// authSlice.js (Después de la migración)
import { createSlice } from "@reduxjs/toolkit";

const authSlice = createSlice({
  name: "auth",
  initialState: {
    isAuthenticated: false,
    user: null,
  },
  reducers: {
    loginSuccess(state, action) {
      state.isAuthenticated = true;
      state.user = action.payload;
    },
    logout(state) {
      state.isAuthenticated = false;
      state.user = null;
    },
  },
});

export const { loginSuccess, logout } = authSlice.actions;
export default authSlice.reducer;
  • Actualiza la configuración del store: Reemplaza el reducer original en la configuración del store con el nuevo slice:
// store.js (Antes de la migración)
import { createStore } from "redux";
import authReducer from "./authReducer";

const store = createStore(authReducer);

export default store;
// store.js (Después de la migración)
import { configureStore } from "@reduxjs/toolkit";
import authReducer from "./authSlice";

const store = configureStore({
  reducer: {
    auth: authReducer,
  },
});

export default store;

Migración de thunks

  • Identifica un thunk para migrar: Selecciona un thunk existente. A continuación, un ejemplo de un thunk para el login:
// authActions.js (Antes de la migración)
export const loginUser = (credentials) => {
  return async (dispatch) => {
    try {
      const user = await api.login(credentials);
      dispatch({ type: "LOGIN_SUCCESS", payload: user });
    } catch (error) {
      console.error(error);
    }
  };
};
  • Migra el thunk utilizando createAsyncThunk: Utiliza createAsyncThunk para definir el thunk en Redux Toolkit:
// authSlice.js (Después de la migración)
import { createAsyncThunk, createSlice } from "@reduxjs/toolkit";
import api from "../api";

export const loginUser = createAsyncThunk(
  "auth/loginUser",
  async (credentials, { rejectWithValue }) => {
    try {
      const user = await api.login(credentials);
      return user;
    } catch (error) {
      return rejectWithValue(error.response.data);
    }
  }
);

const authSlice = createSlice({
  name: "auth",
  initialState: {
    isAuthenticated: false,
    user: null,
    status: "idle",
    error: null,
  },
  reducers: {
    logout(state) {
      state.isAuthenticated = false;
      state.user = null;
    },
  },
  extraReducers: (builder) => {
    builder
      .addCase(loginUser.pending, (state) => {
        state.status = "loading";
      })
      .addCase(loginUser.fulfilled, (state, action) => {
        state.status = "succeeded";
        state.isAuthenticated = true;
        state.user = action.payload;
      })
      .addCase(loginUser.rejected, (state, action) => {
        state.status = "failed";
        state.error = action.payload;
      });
  },
});

export const { logout } = authSlice.actions;
export default authSlice.reducer;

Migración de selectores y actions

  • Actualiza los selectores: Actualiza los selectores para que apunten al nuevo estado del slice. Ejemplo:
// authSelectors.js
export const selectIsAuthenticated = (state) => state.auth.isAuthenticated;
export const selectUser = (state) => state.auth.user;
  • Reemplaza las acciones en los componentes: Reemplaza las acciones antiguas con las acciones generadas por el slice en tus componentes:
// LoginComponent.js (Antes de la migración)
import React from "react";
import { useDispatch } from "react-redux";
import { loginUser } from "./authActions";

const LoginComponent = () => {
  const dispatch = useDispatch();

  const handleLogin = (credentials) => {
    dispatch(loginUser(credentials));
  };

  return (
    <button
      onClick={() => handleLogin({ username: "user", password: "pass" })}
    >
      Login
    </button>
  );
};

export default LoginComponent;
// LoginComponent.js (Después de la migración)
import React from "react";
import { useDispatch } from "react-redux";
import { loginUser } from "./authSlice";

const LoginComponent = () => {
  const dispatch = useDispatch();

  const handleLogin = (credentials) => {
    dispatch(loginUser(credentials));
  };

  return (
    <button
      onClick={() => handleLogin({ username: "user", password: "pass" })}
    >
      Login
    </button>
  );
};

export default LoginComponent;

Construye interfaces de usuarios personalizadas y atractivas
Lleva la formación de tu equipo al siguiente nivel con cursos, talleres y laboratorios prácticos de JavaScript, React, Angular, HTML, CSS y más.
Solicitar más información

Conclusiones

Migrar de Redux a Redux Toolkit puede parecer un reto, pero los beneficios en términos de simplicidad, mantenibilidad y rendimiento hacen que el esfuerzo valga la pena.

Esta librería no solo simplifica la configuración y el uso de Redux, sino que también introduce patrones modernos que facilitan la escalabilidad y el mantenimiento a largo plazo.

Recuerda que en OpenWebinars, dispones de la ruta de aprendizaje Desarrollador frontend con React, en la que profudizarás en el uso de Redux para manejar el estado en aplicaciones basadas en React.

Bombilla

Lo que deberías recordar de la migración de Redux a Redux Toolkit

  • Redux Toolkit reduce drásticamente el código boilerplate necesario para configurar Redux.
  • configureStore simplifica la configuración del store y aplica mejores prácticas por defecto.
  • createSlice combina reducers y acciones en un solo lugar, mejorando la legibilidad y mantenibilidad.
  • createAsyncThunk ofrece una manera más estructurada y automática de manejar acciones asincrónicas.
  • El proceso de migración por partes ayuda a minimizar el riesgo y facilitar la resolución de problemas.
  • Redux Toolkit incluye optimizaciones de rendimiento, pero siempre es recomendable monitorear el rendimiento post-migración.
Compartir este post

También te puede interesar

Icono de la tecnología
Curso

Manejo del estado con Redux y Angular

Intermedio
2 h.

En este curso aprenderás a controlar el estado global de nuestra aplicación Angular de eCommerce mediante Redux a...

Juan Manuel Pérez Toro
4.3
Icono de la tecnología
Curso

Desarrollo web Frontend

Intermedio
17 h. y 51 min.

Uno de los perfiles más demandando por las empresas.

Sergio Rus
4.1