React State Management with Redux Guide
react
redux
state management
Core Concepts
- Store: Holds the state of your application
- Action: Plain object describing what happened
- Reducer: Function that returns the next state
- Dispatch: Method to send actions to the store
Setting up Redux
Install necessary packages:
npm install redux react-redux @reduxjs/toolkit
Creating a Store
import { configureStore } from '@reduxjs/toolkit';
import rootReducer from './reducers';
const store = configureStore({
reducer: rootReducer,
});
export default store;
Defining Actions
// Using Redux Toolkit's createAction
import { createAction } from '@reduxjs/toolkit';
export const increment = createAction('counter/increment');
export const decrement = createAction('counter/decrement');
Creating Reducers
import { createReducer } from '@reduxjs/toolkit';
import { increment, decrement } from './actions';
const initialState = { value: 0 };
const counterReducer = createReducer(initialState, (builder) => {
builder
.addCase(increment, (state, action) => {
state.value++;
})
.addCase(decrement, (state, action) => {
state.value--;
});
});
export default counterReducer;
Connecting React to Redux
import React from 'react';
import { Provider } from 'react-redux';
import store from './store';
import App from './App';
const Root = () => (
<Provider store={store}>
<App />
</Provider>
);
export default Root;
Using Redux in Components
import React from 'react';
import { useSelector, useDispatch } from 'react-redux';
import { increment, decrement } from './actions';
function Counter() {
const count = useSelector((state) => state.counter.value);
const dispatch = useDispatch();
return (
<div>
<button onClick={() => dispatch(decrement())}>-</button>
<span>{count}</span>
<button onClick={() => dispatch(increment())}>+</button>
</div>
);
}
export default Counter;
Async Actions with Redux Thunk
import { createAsyncThunk } from '@reduxjs/toolkit';
export const fetchUserById = createAsyncThunk(
'users/fetchByIdStatus',
async (userId, thunkAPI) => {
const response = await fetch(`https://api.example.com/users/${userId}`);
return response.json();
}
);
// In your reducer
const usersSlice = createSlice({
name: 'users',
initialState: { entities: [], loading: 'idle' },
reducers: {
// ...other reducers
},
extraReducers: (builder) => {
builder
.addCase(fetchUserById.pending, (state, action) => {
state.loading = 'loading';
})
.addCase(fetchUserById.fulfilled, (state, action) => {
state.entities.push(action.payload);
state.loading = 'idle';
});
},
});
Remember, Redux is just one of many state management solutions for React. For simpler applications, React's built-in useState and useContext hooks might be sufficient.