Open In App

How to combine multiple reducers in ReactJS ?

Last Updated : 02 Nov, 2023
Improve
Improve
Like Article
Like
Save
Share
Report

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 structure

The 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

Peek-2023-10-18-15-30



Like Article
Suggest improvement
Share your thoughts in the comments

Similar Reads