Redux desde cero
1. ¿Qué es Redux?
Redux es una librería de manejo de estado global.
Sirve para:
- Guardar en un solo lugar (“store”) el estado compartido de tu aplicación.
- Permitir que cualquier componente pueda leer y actualizar ese estado sin necesidad de pasar props manualmente entre muchos niveles.
👉 Piensa en Redux como un “control remoto universal” que todos los componentes pueden usar para acceder/modificar el estado.
2. Conceptos básicos
-
Store
Es el lugar donde vive el estado global de tu app. -
Action
Es un objeto que describe qué quieres hacer. Ejemplo:
{ type: "INCREMENT" }
-
Reducer
Es una función pura que dice cómo cambia el estado dependiendo de la acción.
Ejemplo:
function counterReducer(state = { count: 0 }, action) {
switch (action.type) {
case "INCREMENT":
return { count: state.count + 1 };
case "DECREMENT":
return { count: state.count - 1 };
default:
return state;
}
}
-
Dispatch
Es la función que manda una acción al store para que el reducer la procese.
3. Primer ejemplo (sin React, solo JS)
import { createStore } from "redux";
// Reducer
function counterReducer(state = { count: 0 }, action) {
switch (action.type) {
case "INCREMENT":
return { count: state.count + 1 };
case "DECREMENT":
return { count: state.count - 1 };
default:
return state;
}
}
// Crear el store
const store = createStore(counterReducer);
// Suscribirse a cambios
store.subscribe(() => {
console.log("Nuevo estado:", store.getState());
});
// Dispatch de acciones
store.dispatch({ type: "INCREMENT" }); // Nuevo estado: { count: 1 }
store.dispatch({ type: "INCREMENT" }); // Nuevo estado: { count: 2 }
store.dispatch({ type: "DECREMENT" }); // Nuevo estado: { count: 1 }
4. Redux con React (ejemplo básico)
Instalación
npm install @reduxjs/toolkit react-redux
Hoy en día se recomienda usar Redux Toolkit porque simplifica mucho la sintaxis.
Paso 1: Crear un slice (estado + reducer + actions)
// store/counterSlice.js
import { createSlice } from "@reduxjs/toolkit";
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;
Paso 2: Configurar el store
// store/index.js
import { configureStore } from "@reduxjs/toolkit";
import counterReducer from "./counterSlice";
export const store = configureStore({
reducer: {
counter: counterReducer,
},
});
Paso 3: Envolver la app con el Provider
// main.jsx
import React from "react";
import ReactDOM from "react-dom/client";
import { Provider } from "react-redux";
import { store } from "./store";
import App from "./App";
ReactDOM.createRoot(document.getElementById("root")).render(
<Provider store={store}>
<App />
</Provider>
);
Paso 4: Usar Redux en un componente
// App.jsx
import React from "react";
import { useSelector, useDispatch } from "react-redux";
import { increment, decrement } from "./store/counterSlice";
export default function App() {
const count = useSelector((state) => state.counter.value); // leer estado
const dispatch = useDispatch(); // para mandar acciones
return (
<div>
<h1>Contador: {count}</h1>
<button onClick={() => dispatch(increment())}>+1</button>
<button onClick={() => dispatch(decrement())}>-1</button>
</div>
);
}
✅ Ahora tu contador funciona con Redux.
Todos los componentes que usen useSelector
para leer counter.value
recibirán automáticamente el estado actualizado.
5. ¿Dónde entra bindActionCreators
?
Con useDispatch
ya casi no se usa, pero si trabajas con connect
o con código más clásico, bindActionCreators
sirve para que tus action creators
ya vengan con dispatch
incluido.
Ejemplo:
import { bindActionCreators } from "redux";
import { increment, decrement } from "./store/counterSlice";
import { useDispatch } from "react-redux";
const dispatch = useDispatch();
const actions = bindActionCreators({ increment, decrement }, dispatch);
// en vez de actions.increment() → {type: 'increment'}
// ahora hace el dispatch automático
actions.increment();
👉 Hasta aquí ya tienes la base sólida de Redux.
Podemos avanzar a un ejemplo más complejo (paginación con sort y filtros) cuando quieras.