How to combine multiple reducers in ReactJS ?
Last Updated :
02 Nov, 2023
To combine multiple reducers in React JS we have a function called combineReducers in the redux. This basically helps to combine multiple reducers into a single unit and use them.
Approach
In React, to combine and implement multiple reducers combineReducers methods are used. It manages multiple reductions and uses them with the defined actions in the redux.
Steps to create React Application
Step 1: Create a React application using the following command:
npx create-react-app example
Step 2: After creating your project folder i.e. example, move to it using the following command:
cd example
Step 3: Install the following modules. From the root directory of your project in the terminal, run the following command:
npm i redux react-redux
Project Structure:
project structureThe updated dependencies in package.json file will look like:
{
"dependencies": {
"@testing-library/jest-dom": "^5.17.0",
"@testing-library/react": "^13.4.0",
"@testing-library/user-event": "^13.5.0",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-redux": "^8.1.3",
"react-scripts": "5.0.1",
"redux": "^4.2.1",
"web-vitals": "^2.1.4"
},
}
Example: Make a simple book list application with the help of redux to understand how to combine multiple reducers.
JavaScript
// Filename - index.js
import React from "react";
import ReactDOM from "react-dom";
import "./index.css";
import App from "./App";
import { Provider } from "react-redux";
import { createStore } from "redux";
import reducers from "./reducers";
const root = ReactDOM.createRoot(
document.getElementById("root")
);
root.render(
<React.StrictMode>
<Provider store={createStore(reducers)}>
<App />
</Provider>
</React.StrictMode>
);
JavaScript
// Filename - App.js
import React from "react";
import { Component } from "react";
import BookList from "./components/book-list";
import "./App.css";
export default class App extends Component {
render() {
return (
<div
style={{
display: "flex",
flexDirection: "column",
justifyContent: "center",
alignItems: "center",
width: "100%",
height: "100vh",
}}
>
{" "}
<h1 className="geeks">GeeksforGeeks</h1>
<BookList />
</div>
);
}
}
JavaScript
// Filename - components/book-list.js
import React, { Component } from "react";
import { connect } from "react-redux";
import { selectBook } from "../actions/index";
import { bindActionCreators } from "redux";
import BookDetail from "./book-detail";
class BookList extends Component {
renderList() {
return this.props.books.map((book) => {
return (
<div
className="item"
key={book.title}
onClick={() =>
this.props.selectBook(book)
}
>
{book.title}
</div>
);
});
}
render() {
return (
<div className="container">
<div className="books">
{this.renderList()}
</div>
<div className="description">
<BookDetail />
</div>
</div>
);
}
}
function mapStateToProps(state) {
return {
books: state.books,
};
}
function mapDispatchToProps(dispatch) {
return bindActionCreators(
{
selectBook: selectBook,
},
dispatch
);
}
export default connect(
mapStateToProps,
mapDispatchToProps
)(BookList);
JavaScript
// Filename - components/book-detail.js
import React, { Component } from "react";
import { connect } from "react-redux";
class BookDetail extends Component {
render() {
if (!this.props.book) {
return (
<div>
<h3>Select a book to get started.</h3>
</div>
);
}
return (
<div>
<h3>Details for:</h3>
<div>Title: {this.props.book.title}</div>
<div>Pages: {this.props.book.pages}</div>
</div>
);
}
}
function mapStateToProps(state) {
return {
book: state.activeBook,
};
}
export default connect(mapStateToProps)(BookDetail);
JavaScript
// Filename - actions/index.js
export function selectBook(book) {
return {
type: "BOOK_SELECTED",
payload: book
};
}
JavaScript
// Filename - reducers/index.js
import { combineReducers } from "redux";
import BooksReducer from "./reducer_book";
import ActiveBook from "./reducer_active_book";
const rootReducer = combineReducers({
books: BooksReducer,
activeBook: ActiveBook
});
export default rootReducer;
JavaScript
// Filename reducers/reducer_active_book.js
export default function active(state = null, action) {
switch (action.type) {
case "BOOK_SELECTED":
return action.payload;
default:
return state;
}
}
JavaScript
// Filename - reducers/reducer_book.js
export default function books() {
return [
{ title: "Javascript The Good Parts", pages: 101 },
{ title: "Harry Potter", pages: 39 },
{ title: "The Dark Tower", pages: 85 },
{ title: "Eloquent Ruby", pages: 1 }
];
}
CSS
/* Filename - App.css */
.App {
text-align: center;
}
.geeks {
color: green;
}
.container {
display: flex;
flex-direction: row;
min-width: 35rem;
margin: 2% auto;
box-shadow: 0px 5px 10px gray;
border-radius: 15px;
padding: 3%;
}
.books {
display: flex;
flex-direction: column;
}
.item {
width: 200px;
background-color: green;
color: white;
margin: 2% auto;
padding: 10px;
border-radius: 10px;
}
.description {
margin: 2% auto;
width: 15rem;
}
Step to run the application: Run the application using the following command
npm start
Output:Â Â Open browser and visit http://localhost:3000/ to see this output
