Clue Mediator

How to implement redux in React.js

๐Ÿ“…March 6, 2020
๐Ÿ—ReactJS

Today we'll show you how to implement redux in React.js. Most of the developers get confused about the implementation of the redux. So today we will show you the redux example step by step.

How to implement redux in React.js, React Redux Tutorial or Example for Beginners, Redux with real-life examples, Integrate redux into your existing react app, use redux concepts in react js, react redux example from scratch, react redux example.

Checkout more articles on ReactJS

What is Redux?

There are multiple definitions in the market but in simple words we can say Redux is used to manage the data at application level in store. Redux will help us to consume and update the store data from any component.

Without wasting time in definition, let's jump on example.

Steps to implement redux in React.js

  1. Overview of redux example
  2. Setup react application
  3. Install redux dependencies
  4. Project structure
  5. Create action types
  6. Create actions
  7. Create reducers
  8. Combine multiple reducers
  9. Create store
  10. Make redux store available to the application
  11. Connect component with the store
  12. Output

1. Overview of redux example

In this article, We are planning to create a simple React application using multiple components like Header, Sidebar, Footer and Content etc.

Now we would like to connect applications with store and consume or update state from several components. The store will contain a counter and tagline.

  • Counter - Counter will be added in the Content and Sidebar component. Where we can increase or decrease counter from Content component and reset counter from Sidebar component only. The counter value will appear the same throughout the application.
  • Tagline - We can have ability to update tagline from Content component and display it in the Header component.

2. Setup react application

First, we have to create a simple react application which contains multiple components. Please refer below link for your reference.

Create React Application using Multiple Components

3. Install redux dependencies

In order to implement redux, we have to install redux dependencies. Run the command below.

npm i redux react-redux

4. Project structure

Follow the below project structure for redux example.

  • `actions` folder - In this folder we'll add action types and several actions.
  • `reducers` folder - Here we'll store all types of reducers and combine it for store creation.
  • `pages` folder - Used to manage components like Header, Footer etc.
  • `store.js` file - Used to create a store for redux application.

Project Structure - Clue Mediator

Project Structure - Clue Mediator

5. Create action types

The action type is nothing but the constant value or unique key which will be used in action and reducer to update the value in store.

Create an `actions` directory and add a new file name as `actionTypes.js` where we will define the type of all the action and use it in actions and reducers.

actions/actionTypes.js

// increase counter
export const INCREMENT = 'INCREMENT';
// decrease counter
export const DECREMENT = 'DECREMENT';
// reset counter
export const RESET = 'RESET';
// set counter title
export const SET_COUNTER_TITLE = 'SET_COUNTER_TITLE';
// set tagline
export const SET_TAGLINE = 'SET_TAGLINE';

6. Create actions

The action returns the simple object to the reducer which contains type and payload. By the use of type & payload, we can update the state in store with the help of reducer.

In today's example, we'll create two actions. One for counter (`counterActions.js`) and another for tagline (`headActions.js`).

actions/counterActions.js

import {
  INCREMENT, DECREMENT, RESET,
  SET_COUNTER_TITLE
} from "./actionTypes";

// to increment the counter
export const incrementCounter = () => ({ type: INCREMENT });

// to decrement the counter
export const decrementCounter = () => ({ type: DECREMENT });

// to reset the counter
export const resetCounter = () => ({ type: RESET });

// to set counter title
export const setCounterTitle = titleText => {
  return {
    type: SET_COUNTER_TITLE,
    payload: {
      title: titleText
    }
  }
}

actions/headActions.js

import {
  SET_TAGLINE
} from "./actionTypes";

// to set the tagline in header
export const setTagline = tagline => {
  return {
    type: SET_TAGLINE,
    payload: {
      tagline
    }
  }
}

7. Create reducers

In simple words, reducer is a function which receives the new value to update the state in store based on action type and payload.

So let's create a directory name as `reducers` and within the directory, create reducers for counter and tagline where we'll write the switch case to update the store based on given action type and payload.

reducers/counterReducer.js

import {
  INCREMENT, DECREMENT, RESET,
  SET_COUNTER_TITLE
} from "../actions/actionTypes";

// define initial state of counter
const initialState = {
  counterTitle: 'Counter',
  count: 0
}

// update store based on type and payload and return the state
export default function common(state = initialState, action) {
  switch (action.type) {
    case INCREMENT:
      return {
        ...state,
        count: state.count + 1
      };
    case DECREMENT:
      return {
        ...state,
        count: state.count - 1
      };
    case RESET:
      return {
        ...state,
        count: 0
      };
    case SET_COUNTER_TITLE:
      const { title } = action.payload;
      return {
        ...state,
        counterTitle: title
      }
    default:
      return state
  }
}

reducers/headReducer.js

import {
  SET_TAGLINE
} from "../actions/actionTypes";

// define initial state of head
const initialState = {
  tagline: 'Demo application created in React App!'
}

// update store based on type and payload and return the state
export default function common(state = initialState, action) {
  switch (action.type) {
    case SET_TAGLINE:
      const { tagline } = action.payload;
      return {
        ...state,
        tagline
      }
    default:
      return state
  }
}

8. Combine multiple reducers

Now combine all reducers together in a single file name as `index.js` and export it for the store.

reducers/index.js

import { combineReducers } from 'redux';
import counter from './counterReducer';
import head from './headReducer';

// to combine all reducers together
const appReducer = combineReducers({
  counter,
  head
});

export default appReducer;

9. Create store

We have to create a store with the help of the combined reducers. In order to do it, we have to create a `store.js` file at the root level of the project.

store.js

import { createStore } from 'redux';
import appReducer from './reducers';

export default createStore(appReducer);

10. Make redux store available to the application

At last, we have to make the redux store available to the entire application. For that redux provide `<Provider />`, Which helps you to link the store with the react application. You have to slightly update the code in `index.js` file.

index.js

import React from 'react';
import ReactDOM from 'react-dom';

import { Provider } from 'react-redux';
import store from './store';

import './index.css';
import App from './App';

ReactDOM.render((
  <Provider store={store}>
    <App />
  </Provider>
), document.getElementById('root'));

11. Connect component with the store

Redux provides a `connect` function to connect your component to the store. With the help of `connect`, we can map store state to the props and map dispatch methods to the props.

Now let's update the existing components to connect with store based on needs.

Header component:

Fetch tagline from store and display it in Header component. For that we have to map state to props and display tagline by the use of the props.

pages/Header.js

import React, { Component } from 'react';
import { connect } from 'react-redux';

class Header extends Component {
  render() {
    const { tagline } = this.props;
    return (
      <div className="header">
        <h1>Redux Application</h1>
        <p>{tagline}</p>
      </div>
    );
  }
}

const mapStateToProps = (state) => {
  return {
    tagline: state.head.tagline
  }
}

export default connect(mapStateToProps)(Header);

Sidebar component:

Now get count for counter from store to display it in Sidebar component and also use `resetCounter` action from `actions/counterActions.js` to reset the count of the counter in the store.

pages/Sidebar.js

import React, { Component } from 'react';
import { connect } from 'react-redux';
import { resetCounter } from "../actions/counterActions";

class Sidebar extends Component {
  render() {
    const { resetCounter, counterObj } = this.props;
    return (
      <div className="side">

        <h2>{counterObj.counterTitle}: {counterObj.count}</h2>
        <input type="button" className="btn" value="Reset Counter" onClick={resetCounter} />

        <h2>Arcu bibendum</h2>
        <h5>Sit amet mattis vulputate</h5>
        <div className="fakeimg" style={{ height: 200 }}>Image</div>
        <p>Non blandit massa enim nec dui nunc mattis enim. Egestas tellus rutrum tellus pellentesque eu tincidunt tortor aliquam nulla..</p>
        <h3>Massa enim</h3>
        <p>Lorem ipsum dolor sit ame.</p>
        <div className="fakeimg" style={{ height: 60 }}>Image</div><br />
        <div className="fakeimg" style={{ height: 60 }}>Image</div><br />
        <div className="fakeimg" style={{ height: 60 }}>Image</div>
      </div>
    );
  }
}

const mapStateToProps = (state) => {
  return {
    counterObj: state.counter
  }
}

const mapDispatchToProps = {
  resetCounter
}

export default connect(mapStateToProps, mapDispatchToProps)(Sidebar);

Content component:

At last, we'll fetch the count for the counter from store to display it and additionally we'll add two buttons for increment and decrement the count. For that we have to use `incrementCounter` and `decrementCounter` action from `actions/counterActions.js`.

Also, we would like to provide the functionality to update the tagline with the help of text input and button elements. By pressing the button, we'll update the tagline in store and it will auto reflect in the header once it is updated in store.

To accomplish this functionality, we have to use `incrementCounter`, `decrementCounter` & `setTagline` from actions.

pages/Content.js

import React, { Component } from 'react';
import { connect } from 'react-redux';
import { incrementCounter, decrementCounter } from "../actions/counterActions";
import { setTagline } from "../actions/headActions";

class Content extends Component {
  constructor(props) {
    super(props);
    this.state = {
      tagline: this.props.tagline
    }
  }
  render() {
    const { tagline } = this.state;
    const { incrementCounter, decrementCounter, counterObj, setTagline } = this.props;
    return (
      <div className="main">

        <div style={{ marginBottom: 20 }}>
          <h2>{counterObj.counterTitle}: {counterObj.count}</h2>
          <input type="button" className="btn" style={{ marginRight: 10 }} value="+1" onClick={incrementCounter} />
          <input type="button" className="btn" value="-1" onClick={decrementCounter} />
        </div>

        <div style={{ marginBottom: 20 }}>
          Tagline: <input type="text" className="tagline" value={tagline} onChange={e => this.setState({ tagline: e.target.value })} />
          <input type="button" style={{ padding: '5px 7px', marginLeft: 10, width: 100 }} value="Set" onClick={() => setTagline(tagline)} />
        </div>

        <h2>Lorem ipsum dolor</h2>
        <h5>quam pellentesque, Dec 10, 2018</h5>
        <div className="fakeimg" style={{ height: 200 }}>Image</div>
        <p>Nisi vitae suscipit..</p>
        <p>Semper quis lectus nulla at. Nullam ac tortor vitae purus faucibus ornare suspendisse. Nunc faucibus a pellentesque sit. Risus quis varius quam quisque id diam vel quam elementum. Ornare aenean euismod elementum nisi quis eleifend quam.</p>
        <br />
        <h2>Placerat vestibulum</h2>
        <h5>elementum integer enim neque, Sep 21, 2018</h5>
        <div className="fakeimg" style={{ height: 200 }}>Image</div>
        <p>Bibendum est ultricies..</p>
        <p>Semper quis lectus nulla at. Nullam ac tortor vitae purus faucibus ornare suspendisse. Nunc faucibus a pellentesque sit. Risus quis varius quam quisque id diam vel quam elementum.</p>
      </div>
    );
  }
}

const mapStateToProps = (state) => {
  return {
    counterObj: state.counter,
    tagline: state.head.tagline
  }
}

const mapDispatchToProps = {
  incrementCounter,
  decrementCounter,
  setTagline
}

export default connect(mapStateToProps, mapDispatchToProps)(Content);

12. Output

Run the project and check the output.

Output - How to implement redux in React.js - Clue Mediator

Output - How to implement redux in React.js - Clue Mediator

That's it for today. In the next article, we will show you the API call with redux.
Thank you for reading. Happy Coding!

Demo & Source Code

Github Repository StackBlitz Project