Integrating Redux into a Next app streamlines complex state management. This tutorial outlines steps to seamlessly integrate Redux with Next, demonstrating the creation of a basic counter with increment and decrement buttons, with Redux managing its state.
Approach to integrate Redux in Next Application:
As Next is built on React, we’ll utilize the ‘redux‘ and ‘react-redux‘ node packages. Our process involves creating a Redux store, defining actions and reducers, wrapping our app’s base with ‘Provider‘, and utilizing ‘useSelector‘ and ‘useDispatch‘ hooks to interact with the Redux data layer.
Steps to Set Up the App:
Step 1: Open the terminal and create a NextJS app using the following command:
npx create-next-app next-redux
Step 2: Switching into the project directory:
cd next-redux
Step 3: Install ‘redux’ and ‘react-redux’ and ‘@reduxjs/toolkit’ package by running the following command:
npm install redux react-redux @reduxjs/toolkit
Project Structure:
The updated dependencies in package.json file will look like:
"dependencies": {
"@reduxjs/toolkit": "^2.1.0",
"next": "14.1.0",
"react": "^18",
"react-dom": "^18",
"react-redux": "^9.1.0",
"redux": "^5.0.1"
}
Step 4: In this step we will setup our redux store. Create a folder named ‘redux’ at the root of your project. Further create a file ‘store.js’ inside it.
Step 5: Update ‘store.js’ to include the counterReducer.
Step 6: Wrap the base of the application pages/_app.js with Provider from react-redux.
Step 7: Make the use of state the we just created by opening pages/index.js and writing the following logic. The explanation of each and every line is written in comments.
Explanation:
- Initial state for the counter is set to 40 as the default value.
- The ‘@reduxjs/toolkit’ library’s ‘createSlice’ function is utilized to establish a slice.
- Within reducers, ‘increment’ and ‘decrement’ functions are defined to respectively increase or decrease the counter value.
- Action creators (increment, decrement) are destructured and exported, along with the reducer function created by ‘createSlice’.
Example: Below is the code example for the complete working of the redux:
// Import necessary dependencies import Image from "next/image" ;
import { Inter } from "next/font/google" ;
import { useDispatch,
useSelector
} from "react-redux" ;
// Import action creators from the counter reducer import { decrement,
increment
} from "@/redux/counterReducer" ;
// Initialize the Inter // font with Latin subset const inter = Inter({ subsets: [ "latin" ] });
// Define the Home component export default function Home() {
// Access the counter state
// from the Redux store
const counter =
useSelector((state) => state.counter);
// Get the dispatch function to
// send actions to the Redux store
const dispatch = useDispatch();
// Handler function for decreasing the counter value
const handleDecrease = () => {
// Dispatch the decrement action to the Redux store
dispatch({
// Using the imported decrement action creator
type: decrement,
});
};
// Handler function for increasing the counter value
const handleIncrease = () => {
// Dispatch the increment action to the Redux store
dispatch({
// Using the imported increment action creator
type: increment,
});
};
// Render the component
return (
<div className= "mx-auto w-[400px] h-[400px]
flex items-center space-x-10" >
{ /* Display a heading for the counter */ }
<h1 className= "min-w-36 text-xl tracking-wider" >
Counter with Redux + Next
</h1>
{ /* Button to decrease the counter value */ }
<button onClick={handleDecrease}
className= "bg-red-600 text-white p-4" >
DECREASE
</button>
{ /* Display the current counter value */ }
<h1>{counter.value}</h1>
{ /* Button to increase the counter value */ }
<button onClick={handleIncrease}
className= "bg-green-600 text-white p-4" >
INCREASE
</button>
</div>
);
} |
//pages/_app.js import "@/styles/globals.css" ;
import { store } from "../redux/store" ;
import { Provider } from "react-redux" ;
export default
function App(
{
Component,
pageProps
}) {
return (
<Provider store={store}>
<Component {...pageProps} />
</Provider>
)
} |
// counterReducer.js // Import the createSlice function // from the '@reduxjs/toolkit' library import { createSlice } from "@reduxjs/toolkit" ;
// Define the initial state for the counter reducer const initialState = { value: 40,
}; // Create a slice using createSlice, which automatically // generates action creators and reducer functions export const counterSlice = createSlice({
name: "counter" , // Specify the name for the slice
initialState, // Set the initial state
reducers: {
increment: (state) => {
// Reducer function for incrementing
// the counter value by 1
state.value += 1;
},
decrement: (state) => {
// Reducer function for decrementing
// the counter value by 1
state.value -= 1;
},
incrementByAmount: (state, action) => {
// Reducer function for incrementing
// the counter value by a specific amount
// Modify the state using the payload from the action
state.value += action.payload;
},
},
});
// Export the action creators generated by createSlice export const { increment,
decrement,
incrementByAmount
} = counterSlice.actions; // Export the reducer function generated by createSlice export default counterSlice.reducer;
|
import { configureStore } from '@reduxjs/toolkit'
import counterReducer from './counterReducer'
export const store = configureStore({ reducer: {
counter: counterReducer,
},
}) |
Step to run the app:
npm run dev
Output: Navigate to http://localhost:3000/