O estado de componente no React funciona bem até que múltiplos componentes precisem dos mesmos dados e o prop drilling vira algo insuportável. O Redux fornece um container de estado único e previsível que qualquer componente pode ler e para o qual pode disparar ações.
TL;DR: Uma referência React + Redux: setup do store, actions, reducers, selectors e middleware Thunk para operações assíncronas.
Stack: React, Redux, Redux Toolkit, React-Redux
Nível: Intermediário
Tempo de leitura: ~18 min
O problema que o Redux resolve
Em um app típico, você tem muitos componentes cada um com seu próprio estado. Quando os componentes começam a depender dos dados uns dos outros, você acaba passando props por camadas de componentes que nem as usam , isso é prop drilling. O Redux move o estado compartilhado para fora dos componentes e para dentro de um store central, para que qualquer componente possa ler ou atualizar sem uma cadeia de relay de props.
Setup
npx create-react-app meu-app
yarn add redux react-redux immer
yarn add redux-devtools-extension
Reducer (store/modules/shop/reducer.js)
import produce from 'immer';
const INITIAL_STATE = { customer: {}, items: [] };
function shop(state = INITIAL_STATE, action) {
switch (action.type) {
case 'SET_CUSTOMER':
return produce(state, (draft) => {
draft.customer = action.customer;
});
case 'ADD_ITEM':
return produce(state, (draft) => {
draft.items.push(action.item);
});
default:
return state;
}
}
export default shop;
Root reducer e store (store/index.js)
import { combineReducers } from 'redux';
import shop from './modules/shop/reducer';
export default combineReducers({ shop });
// store/index.js
import { createStore } from 'redux';
import rootReducer from './modules/rootReducer';
const store = createStore(rootReducer, window.__REDUX_DEVTOOLS_EXTENSION__?.());
export default store;
Conectar ao app (index.js)
import { Provider } from 'react-redux';
import store from './store';
ReactDOM.render(
<Provider store={store}>
<App />
</Provider>,
document.getElementById('root')
);
Disparando actions
import { useDispatch } from 'react-redux';
const dispatch = useDispatch();
dispatch({ type: 'SET_CUSTOMER', customer: { name: 'Allan', age: 30 } });
Lendo do store
import { useSelector } from 'react-redux';
const customer = useSelector((state) => state.shop.customer);
const items = useSelector((state) => state.shop.items);
O que você construiu
Um setup Redux com estado centralizado, actions, reducers usando Immer para imutabilidade, e hooks para leitura e dispatch.
Próximos passos
- Use o Redux Toolkit (createSlice, createAsyncThunk) em vez do Redux puro. Elimina a maior parte do boilerplate e é a abordagem oficial recomendada.
- Use selectors com memoização via reselect para evitar re-renders desnecessários ao ler do store.
- Redux é excessivo para muitos apps. Para estado do servidor (dados de API), React Query ou SWR é mais simples, e para estado de UI local, useState e useContext geralmente bastam.
Dúvidas ou feedback? Me encontre no LinkedIn ou GitHub.