Construyendo tu Reino con Redux Toolkit: Una Guía Completa
Tags: redux, react, tutorial
Published: 2023-10-09 22:32:22

Imagina que estás construyendo un gran reino en una vasta tierra. Este reino es tu aplicación de React, y dentro de este reino, hay diversas partes, cada una con sus propias responsabilidades y recursos. Para mantener el orden y tomar decisiones para todo el reino, necesitas un consejo central que gestione la información y los comandos.

Así es como Redux Toolkit entra en juego como el "Consejo Central" de tu reino:

**El Rey (Redux Toolkit):**

En nuestro reino, Redux Toolkit es como el rey sabio y justo. Sirve como la autoridad central para gestionar y almacenar la información importante (estado) que tu reino (aplicación de React) necesita para funcionar.

**Los Consejeros (Reducers):**

El rey no gestiona todo solo; tiene un consejo de consejeros (reducers). Cada consejero es responsable de una área específica del reino, como el tesoro, el ejército o la agricultura. De manera similar, en Redux Toolkit, los reducers son responsables de manejar diferentes partes del estado de tu aplicación.

```jsx
const treasuryReducer = (state, action) => { /* ... */ };
const armyReducer = (state, action) => { /* ... */ };
const agricultureReducer = (state, action) => { /* ... */ };
```

**Los Mensajeros (actions):**

Los consejeros no pueden tomar decisiones por sí solos; dependen de los mensajeros (actions) para transmitir mensajes de diferentes partes del reino al consejo. En Redux Toolkit, las acciones son como mensajeros que llevan información y solicitudes para cambiar el estado.

```jsx
const increaseGold = (amount) => ({ 
type: 'INCREASE_GOLD', payload: amount });
```

**El Pergamino de Leyes (Store):**

Para mantener toda la información importante en un solo lugar, el consejo mantiene un gran pergamino (store). Este pergamino contiene registros de todas las decisiones pasadas e información necesaria para gobernar el reino. En Redux Toolkit, el store contiene el estado actual y todas las acciones que se han despachado.

**Las Reuniones del Consejo (Middleware):**

Durante las reuniones del consejo (middleware), los consejeros y los mensajeros pueden proponer nuevas leyes (funciones middleware). Estas leyes pueden verificar, modificar o incluso rechazar los cambios propuestos para el reino. Por ejemplo, puedes tener middleware para registrar acciones, manejar tareas asíncronas o hacer cumplir ciertas reglas. Las funciones middleware en Redux son funciones que interceptan y procesan acciones antes de que lleguen a los reducers.

**El Escriba (createSlice):**

Para simplificar el proceso de crear consejeros (reducers), tienes un hábil escriba (createSlice). El escriba puede redactar informes de consejeros (reducers) con menos esfuerzo, ya que entiende muy bien la estructura de estos informes. Esto se asemeja al uso de `createSlice` de Redux Toolkit para crear reducers de manera más eficiente.

**Los Heraldos (Selectors):**

En tu reino, los heraldos (selectors) son responsables de entregar mensajes importantes a los ciudadanos (componentes). Pueden acceder a la información del gran pergamino (store) y compartirla con los habitantes de la ciudad. Los selectores ayudan a los componentes a recuperar y mostrar el estado del store.

**La Tesorería (Actualizaciones Inmutables):**

La tesorería (actualizaciones inmutables) asegura que cuando se realicen cambios en el oro (estado), se registren cuidadosamente y se preserven las reservas originales de oro. Esto es similar al principio de inmutabilidad en Redux Toolkit, donde los cambios de estado resultan en una nueva copia del estado para mantener el historial de cambios.

## ¡Construyamos un reino juntos!

Ahora que hemos explorado el papel de Redux Toolkit en la gestión de tu reino, pongámoslo en práctica con un ejemplo sencillo. Administraremos la tesorería del reino como punto de partida.

**Estructura de Carpetas:**

```txt
- src
  - store
    - treasurySlice.js
  - components
    - Treasury.js
  - App.js
```

### Paso 1: Configurar Redux Toolkit

Primero, debes configurar Redux Toolkit en tu aplicación. Asegúrate de tener Redux y Redux Toolkit instalados:

```
pnpm install @reduxjs/toolkit react-redux
```

### Paso 2: Definir la logica de la Tesorería (Treasury Slice)

¿Recuerdas cómo comparamos los reducers de Redux Toolkit con consejeros responsables de tareas específicas?

Ahora crearemos un consejero de tesorería usando `createSlice` de Redux Toolkit. Aquí definiremos nuestros reducers y actions que relacionamos con mensajeros.

```jsx
// src/store/treasurySlice.js
import { createSlice } from '@reduxjs/toolkit';

const treasurySlice = createSlice({
  name: 'treasury',
  initialState: { gold: 1000 }, // Initial state

  reducers: {
    increaseGold: (state, action) => {
      state.gold += action.payload;
    },
    decreaseGold: (state, action) => {
      state.gold -= action.payload;
    },
  },
});

export const { increaseGold, decreaseGold } = treasurySlice.actions;
export default treasurySlice.reducer;
```

### Paso 3: Configurar la Tienda (Store)

En la misma carpeta donde se encuentra `treasurySlice.js`, crea un archivo llamado `store.js` para configurar tu tienda Redux. Aquí configuraremos nuestra tienda Redux para gestionar las decisiones de nuestro consejero de tesorería:

```jsx
// src/store/store.js
import { configureStore } from '@reduxjs/toolkit';
import treasuryReducer from './treasurySlice';

const store = configureStore({
  reducer: {
    treasury: treasuryReducer, // Add your reducer here
  },
});

export default store;
```

### Paso 4: Crear Componentes

Ahora, creemos un componente para interactuar con la tesorería. Crea un archivo `Treasury.js` en la carpeta `components`, aquí encontraremos los selectores, que son funciones que permiten a los componentes recuperar piezas específicas del estado desde la tienda (store):

```jsx
// src/components/Treasury.js
import React from 'react';
import { useDispatch, useSelector } from 'react-redux';
import { increaseGold, decreaseGold } from '../store/treasurySlice';

function Treasury() {
  const gold = useSelector((state) => state.treasury.gold);
  const dispatch = useDispatch();

  const handleIncreaseGold = () => {
    dispatch(increaseGold(100));
  };

  const handleDecreaseGold = () => {
    dispatch(decreaseGold(50));
  };

  return (
    <div>
      <h2>Treasury</h2>
      <p>Gold: {gold}</p>
      <button onClick={handleIncreaseGold}>Increase Gold</button>
      <button onClick={handleDecreaseGold}>Decrease Gold</button>
    </div>
  );
}

export default Treasury;
```

### **Paso 5: Usa el componente Tesorería en App.js**

Basándonos en la estructura del consejo, ahora incluimos el componente **`Treasury`** en nuestro archivo **`App.js`**:

```jsx
// src/App.js
import React from 'react';
import { Provider } from 'react-redux';
import store from './store/store';
import Treasury from './components/Treasury';

function App() {
  return (
    <Provider store={store}>
      <div className="App">
        <h1>Kingdom Management</h1>
        <Treasury />
      </div>
    </Provider>
  );
}

export default App;
```

**Paso 6: Ejecuta tu aplicación**

Con todo configurado, puedes ejecutar tu aplicación React, y tendrás un componente Tesorería que puede aumentar y disminuir el oro del reino, administrado por Redux Toolkit.

Este es un ejemplo simplificado, pero demuestra la estructura y buenas prácticas de Redux Toolkit para gestionar el estado dentro de tu aplicación React.

## **Expandiendo tu reino: gestionando múltiples estados**

Ahora, vamos a expandir nuestra aplicación de gestión del reino para incluir estados adicionales. En este ejemplo ampliado, gestionaremos no sólo la tesorería sino también la población y la fuerza militar del reino. También demostraremos cómo manejar múltiples slices usando Redux Toolkit.

**Estructura de carpetas:**

```txt
- src
  - store
    - treasurySlice.js
    - populationSlice.js
    - militarySlice.js
    - store.js
  - components
    - Treasury.js
    - Population.js
    - Military.js
  - App.js

```

### **Paso 1: Define slices adicionales**

Crea slices para la población y el ejército en archivos separados, similares al archivo **`treasurySlice.js`**. Por ejemplo:

```jsx
// src/store/populationSlice.js
import { createSlice } from '@reduxjs/toolkit';

const populationSlice = createSlice({
  name: 'population',
  initialState: { count: 1000 },
  reducers: {
    increasePopulation: (state, action) => {
      state.count += action.payload;
    },
    decreasePopulation: (state, action) => {
      state.count -= action.payload;
    },
  },
});

export const { increasePopulation, decreasePopulation } = populationSlice.actions;
export default populationSlice.reducer;

```

```jsx
// src/store/militarySlice.js
import { createSlice } from '@reduxjs/toolkit';

const militarySlice = createSlice({
  name: 'military',
  initialState: { strength: 500 },
  reducers: {
    increaseMilitaryStrength: (state, action) => {
      state.strength += action.payload;
    },
    decreaseMilitaryStrength: (state, action) => {
      state.strength -= action.payload;
    },
  },
});

export const { increaseMilitaryStrength, decreaseMilitaryStrength } = militarySlice.actions;
export default militarySlice.reducer;
```

### **Paso 2: Configura el store con múltiples slices**

Actualiza el archivo **`store.js`** para incluir todos los slices:

```jsx
// src/store/store.js
import { configureStore } from '@reduxjs/toolkit';
import treasuryReducer from './treasurySlice';
import populationReducer from './populationSlice';
import militaryReducer from './militarySlice';

const store = configureStore({
  reducer: {
    treasury: treasuryReducer,
    population: populationReducer,
    military: militaryReducer,
  },
});

export default store;
```

### **Paso 3: Crea componentes adicionales**

Crea componentes para la gestión de la población y el ejército, similares al componente **`Treasury.js`**. Por ejemplo, **`Population.js`** y **`Military.js`**.

### **Paso 4: Usa los nuevos componentes en App.js**

En tu archivo **`App.js`**, incluye los nuevos componentes junto con el componente **`Treasury`** para gestionar todos los aspectos de tu reino:

### **Paso 5: Ejecuta tu aplicación extendida**

Ahora, cuando ejecutes tu aplicación, tendrás componentes para gestionar la tesorería, la población y la fuerza militar de tu reino, usando Redux Toolkit para la gestión del estado. Puedes ampliar este concepto para gestionar más aspectos de tu reino o aplicación según sea necesario.

Siguiendo este patrón, puedes gestionar eficazmente múltiples slices de estado en tu aplicación React usando Redux Toolkit mientras mantienes tu código organizado y mantenible.

## ¿Pero necesito crear un slice para cada nuevo estado?

Puedes gestionar múltiples piezas de estado dentro de un solo slice si están relacionadas y pertenecen al mismo dominio de tu aplicación. Redux Toolkit’s **`createSlice`** te permite definir múltiples piezas de estado dentro de un solo slice, lo que facilita organizar los datos relacionados.

Por ejemplo, puedes tener un solo slice que gestione tanto la tesorería como los diferentes tipos de fuerza militar:

```jsx
// src/store/kingdomSlice.js
import { createSlice } from '@reduxjs/toolkit';

const kingdomSlice = createSlice({
  name: 'kingdom',
  initialState: {
    treasury: {
      gold: 1000,
      silver: 500,
      bronze: 300,
    },
    military: {
      chivalry: 100,
      lance: 400,
      archers: 300,
    },
  },
  reducers: {
    // Treasury-related actions
    increaseGold: (state, action) => {
      state.treasury.gold += action.payload;
    },
    decreaseGold: (state, action) => {
      state.treasury.gold -= action.payload;
    },
    // Military-related actions
    increaseChivalry: (state, action) => {
      state.military.chivalry += action.payload;
    },
    decreaseChivalry: (state, action) => {
      state.military.chivalry -= action.payload;
    },
    // Add more actions for other aspects of the kingdom
  },
});

export const {
  increaseGold,
  decreaseGold,
  increaseChivalry,
  decreaseChivalry,
} = kingdomSlice.actions;
export default kingdomSlice.reducer;
```

En este ejemplo, tenemos un solo slice **`kingdom`** que gestiona tanto el estado relacionado con la tesorería como con el ejército. Cada parte del estado se organiza dentro del objeto de estado **`kingdom`**. Puedes definir acciones separadas para cada aspecto del reino (tesorería, ejército, etc.) y actualizarlos independientemente.

Al usar un solo slice para el estado relacionado, mantienes el código organizado y mantenible. Sin embargo, es esencial encontrar un equilibrio entre la granularidad y la organización. Si encuentras que tu aplicación se vuelve demasiado compleja o que diferentes partes del estado no pertenecen lógicamente juntas, podría tener sentido crear slices separados para una mejor separación de responsabilidades.