Redux Toolkit With React
Introduction:
Redux Toolkit is a global state management library that makes it easier for developers to handle and organize the application's data by providing helpful tools and clear rules, simplifying the process of managing the state.
What is Global state management?
- Global state management is like having a central hub for the data, making it easy to access and update the data across the components.
Why do we need Global state management?
State Sharing Across Components
Single Source of Truth
Avoidance of Prop Drilling
Installing Redux Toolkit:
npm install @reduxjs/toolkit
- For installing the Redux Toolkit package.npm install react-redux
- This package will help us to connect redux with react
Use yarn add
instead of npm install
if you prefer yarn
File Structure:
/src
|-- App.js
|-- features
| |-- counter
| |-- CounterComponent.js
| |-- counterSlice.js
|
|-- store
| |-- store.js
|
|-- index.js
I usually organize my Redux related files in the 'features' folder with the structure described above.
Boilerplate:
// store/store.js
import { configureStore } from '@reduxjs/toolkit';
export const store = configureStore({
reducer: {},
});
configureStore
is a function provided by the Redux Toolkit library that helps us create the store.The
reducer
is where you list the reducers that handle different parts of your app's data.
// features/counter/counterSlice.js
import { createSlice } from '@reduxjs/toolkit';
const initialState = {
// Some initial values
};
const counterSlice = createSlice({
name: 'counter', // name of the slice
initialState, // Initial state for the slice
reducers: {},
});
createSlice
function from Redux Toolkit. That helps create Redux slices, which include the reducer functions and actions related to a specific part of the state.reducers
field is where you will define the functions that handle state changes for the feature.
Connect Redux Store to React:
// index.js
import React from 'react';
import ReactDOM from 'react-dom';
import App from './app/App';
import { Provider } from 'react-redux';
import { store } from './store/store';
ReactDOM.render(
<Provider store={store}>
<React.StrictMode>
<App />
</React.StrictMode>
</Provider>,
document.getElementById('root')
);
<Provider store={store}>
Wraps your entire React application with theProvider
component and passes the store as a prop. This ensures that the Redux store is available to all components in the application.
Creating Reducers:
// features/counter/counterSlice.js
import { createSlice } from '@reduxjs/toolkit';
const initialState = {
value: 0,
};
const counterSlice = createSlice({
name: 'counter',
initialState,
reducers: {
increment: (state, action) => {
state.value += action.payload;
},
decrement: (state, action) => {
state.value -= action.payload;
},
},
});
export const { increment, decrement } = counterSlice.actions;
export default counterSlice.reducer;
Reducers define functions inside the
reducers
object. In this case, we haveincrement
anddecrement
reducers. When using Redux, we avoid mutable logic, but Redux Toolkit (RTK) uses a package called Immer, which automatically converts our mutable logic into immutable logic.The
increment
reducer takes the current state (state
) and an action (action
). It increments thevalue
property by the payload provided in the action.The
decrement
reducer takes the current state (state
) and an action (action
). It decrements thevalue
property by the payload provided in the action.Both the state and action are automatically handled by RTK (Redux Toolkit).
Exports action functions (
increment
anddecrement
) that can be used in components to dispatch actions. Also, export thecounterSlice.reducer
itself for managing the state in Redux.
Redux Store Configuration:
// store.js
import { configureStore } from '@reduxjs/toolkit';
import counterReducer from '../features/counter/counterSlice';
export const store = configureStore({
reducer: {
counter: counterReducer,
},
});
export default store;
- Import the
counterReducer
from the location where it's defined. This assumes you have a Redux slice namedcounterSlice
in thefeatures/counter
directory.
Using in React:
// features/counter/CounterComponent.js
import { useSelector, useDispatch } from 'react-redux';
import { increment, decrement } from './counterSlice';
const CounterComponent = () => {
const counterValue = useSelector((state) => state.counter.value);
const dispatch = useDispatch();
return (
<div>
<p>Counter Value: {counterValue}</p>
<button onClick={() => dispatch(increment())}>Increment</button>
<button onClick={() => dispatch(decrement())}>Decrement</button>
</div>
);
};
Importing Hooks and Actions:
import { useSelector, useDispatch } from 'react-redux';
: Import theuseSelector
anduseDispatch
hooks fromreact-redux
. These hooks allow the component to interact with the Redux store.import { increment, decrement } from './counterSlice';
: Import theincrement
anddecrement
action functions fromcounterSlice
. These actions are used to dispatch changes to the Redux store.
Using Redux Hooks and Actions:
const counterValue = useSelector((state) => state.counter.value);
: Utilize theuseSelector
hook to retrieve thecounter.value
from the Redux store. This value represents the current count managed by Redux.const dispatch = useDispatch();
: Employ theuseDispatch
hook to obtain thedispatch
function, enabling the component to dispatch actions to the Redux store."
Conclusion:
Simplified State Management: Redux Toolkit streamlines state management in React applications.
Clear Structure: The toolkit provides a clear structure, enhancing code organization and readability.