How to Integrate Redux Inside a React App

Here are the steps to integrate a React application with Redux.

Step 1: Install React.js

Type the following command.

npm install -g create-react-app

create-react-app postreactredux
How To Connect React and Redux With Example

Step 2: Install Redux and react-redux.

Type the following command to install both of the libraries.

npm install redux react-redux --save

# or

yarn add redux react-redux

Also, install Bootstrap 4 using the following command.

npm install bootstrap --save

Now, import this file inside src >> index.js.

// index.js

import '../node_modules/bootstrap/dist/css/bootstrap.min.css';

Step 3: Create a NewPost component.

If using react and redux together, then separation of concern is there. This means there are two types of components.

  1. Dumb Components
  2. Smart Component(Containers)

Dumb components render the data and do not care about logic. They have nothing to do with a redux store.

Smart components are concerned about logic and are directly connected to the store.

Now, inside the src foldercreate one file called NewPost.js.

// NewPost.js

import React from 'react';

class NewPost extends React.Component {
  state = {
    title: '',
    body: ''
  };

  handleInputChange = e => {
    this.setState({
      [e.target.name]: e.target.value
    });
  };

  handleSubmit = e => {
    e.preventDefault();
    if (this.state.title.trim() && this.state.body.trim()) {
      console.log(this.state);
      this.handleReset();
    }
  };

  handleReset = () => {
    this.setState({
      title: '',
      body: ''
    });
  };

  render() {
    return (
      <div>
          <form onSubmit={ this.handleSubmit }>
          <div className="form-group">
              <input
              type="text"
              placeholder="Title"
              className="form-control"
              name="title"
              onChange={ this.handleInputChange }
              value={ this.state.title }
            />
          </div>
          <div className="form-group">
            <textarea
              cols="19"
              rows="8"
              placeholder="Body"
              className="form-control"
              name="body"
              onChange={ this.handleInputChange }
              value={ this.state.body }>
            </textarea>
          </div>
          <div className="form-group">
            <button type="submit" className="btn btn-primary">Add Post</button>
            <button type="button" className="btn btn-warning" onClick={ this.handleReset }>
              Reset
            </button>
          </div>
        </form>
      </div>
    );
  }
}

export default NewPost;

So, this component has two form fields.

  1. title
  2. body

When the user submits the form, we can see both the form fields’ values inside the console.

We must import this NewPost.js file inside the src >> App.js file.

// App.js

import React, { Component } from 'react';
import NewPost from './components/NewPost';

import '../node_modules/bootstrap/dist/css/bootstrap.min.css';

class App extends Component {
  render() {
    return (
      <div className="container">
        <div className="row">
          <div className="col-md-6">
            <NewPost />
          </div>
          <div className="col-md-6">
            Display Post
          </div>
        </div>
      </div>
    );
  }
}

export default App;

Save the file and start the development server with the following command.

Redux React Tutorial

Step 4: Create actions.

Inside the src folder, create three more folders, and their names are the following.

  1. containers
  2. reducers
  3. actioFirstrst, inside the actions folder, create one file called types.js.

Write the following code inside it.

// types.js

export const ADD_POST = 'ADD_POST';
export const DELETE_POST = 'DELETE_POST';

These are action types. When the user submits the form, we need to call these actions. So when a user creates a post, we will call ADD_POST action.

This action then calls the reducer function and adds value to the store.

So we can not directly modify the store; we need to create an action and then call the reducer function to alter the store’s state.

Same as a delete, when we try to delete any post, the DELETE_POST action will be triggered.

Now, that action returns an object that contains two properties.

  1. Action type
  2. Payload

We have two actions for our demos, so create one file inside the src >> actions folder called index.js.

But, before that, we need every post ID, so we use the npm library called UUID for generating ID on the client side.

npm install uuid --save

# or

yarn add uuid

Write the following code inside the src >> actions >> index.js file.

// actions >> index.js

import uuidv4 from 'uuid/v4';
import { ADD_POST, DELETE_POST } from './types';

export const createPost = ({ title, body }) => ({
  type: ADD_POST,
  payload: {
    id: uuidv4(),
    title,
    body
  }
});

export const deletePost = id => ({
  type: DELETE_POST,
  payload: {
    id
  }
});

So, the createPost function accepts the title and body as a parameter and returns an object.

We add an extra payload called id to render different posts and delete them according to their IDs.

Step 5: Create rootReducer and postReducer.

Inside the reducers folder, create one file called postReducer.js.

// postReducer.js

import { ADD_POST, DELETE_POST } from '../actions/types';

export default function postReducer(state = [], action) {
  switch (action.type) {
    case ADD_POST:
      return [...state, action.payload];
    case DELETE_POST:
      return state.filter(post => post.id !== action.payload.id);
    default:
      return state;
  }
}

So, if the action type matches the fired action, it will modify the store and change the current state.

Now, create an index.js file inside the reducers folder. Then, write the following code inside it.

// index.js

import { combineReducers } from 'redux';
import posts from './postReducer';

export default combineReducers({
    posts: posts
});

Step 6: Configure Store.

Import this index.js reducer file inside src >> index.js file.

So, our final src >> index.js file looks like below.

// src >> index.js

import React from 'react';
import ReactDOM from 'react-dom';
import { createStore } from 'redux';
import { Provider } from 'react-redux';

import App from './App';
import rootReducer from './reducers';

import registerServiceWorker from './registerServiceWorker';

const store = createStore(rootReducer);

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

registerServiceWorker();

Step 7: Create a container component.

Inside the containers folder, create a component called CreatePost.js.

// CreatePost.js

import { connect } from 'react-redux';
import { createPost } from '../actions';
import NewPost from '../components/NewPost';

const mapDispatchToProps = dispatch => {
  return {
    onAddPost: post => {
      dispatch(createPost(post));
    }
  };
};

export default connect(
  null,
  mapDispatchToProps
)(NewPost);

We have connected the NewPost component to the Redux store.

We have created the higher-order component of the NewPost.js file, and that is a CreatePost.js file.We import this CreatePost.js file inside the src >> App.js file.

// src >> App.js

import React, { Component } from 'react';
import CreatePost from './containers/CreatePost';

import '../node_modules/bootstrap/dist/css/bootstrap.min.css';

const stylesApp = {
  marginTop: 40
}

class App extends Component {
  render() {
    return (
      <div className="container">
        <div className="row" style={ stylesApp }>
          <div className="col-md-6">
            <CreatePost />
          </div>
          <div className="col-md-6">
            Display Post
          </div>
        </div>
      </div>
    );
  }
}

export default App;

Now, when the user submits the form, we can trigger an action, and that action call the reducer and modify the global state.

So, we can now access the action inside the NewPost.js file.

// NewPost.js

handleSubmit = e => {
  e.preventDefault();
  if (this.state.title.trim() && this.state.body.trim()) {
    this.props.onAddPost(this.state);
    this.handleReset();
  }
};

So, now you can track the state inside the store. You can modify the state through actions.

Step 8: Display the Post.

Create a component inside the components folder called Post.js and write the following code inside it. The Post.js component is responsible for rendering out all the Posts.

// Post.js

import React from 'react';

const styles = {
  borderBottom: '2px solid #eee',
  background: '#fafafa',
  margin: '.75rem auto',
  padding: '.6rem 1rem',
  maxWidth: '500px',
  borderRadius: '7px'
};

export default ({ post: { title, body, id }, onDelete }) => {
  return (
    <div style={ styles }>
      <h2>{ title }</h2>
      <p>{ body }</p>
      <button className="btn btn-danger" type="button" onClick={() => onDelete(id)}>
        Remove
      </button>
    </div>
  );
};

So, this component only accepts the title, body, and id data and renders it.

It also accepts the onDelete() function that can trigger the delete action, and then that action calls the postReducer function and deletes the post and state that it has been updated, and our UI will be updated.

Inside the containers folder, create one container component called PostList.js file and write the following code.

// PostList.js

import React from 'react';
import { connect } from 'react-redux';
import Post from '../components/Post';
import { deletePost } from '../actions';

function PostList({ posts, onDelete }) {
  return (
    <div>
      {posts.map(post => {
        return (
          <Post post={ post } onDelete={ onDelete } key={ post.id } />
        );
      })}
    </div>
  );
}

const mapStateToProps = state => {
  return {
    posts: state.posts
  };
};

const mapDispatchToProps = dispatch => {
  return {
    onDelete: id => {
      dispatch(deletePost(id));
    }
  };
};

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

Now, this component gets the latest state from the store. This component is notified when a new post is added because it is directly connected to the store.

If the delete action is triggered, it will filter out that post and display the remaining postThethe final thing is importing this PostList.js component inside the src >> App.js file.

// src >> App.js

import React, { Component } from 'react';
import CreatePost from './containers/CreatePost';
import PostList from './containers/PostList';

import '../node_modules/bootstrap/dist/css/bootstrap.min.css';

const stylesApp = {
  marginTop: 40
}

class App extends Component {
  render() {
    return (
      <div className="container">
        <div className="row" style={ stylesApp }>
          <div className="col-md-6">
            <CreatePost />
          </div>
          <div className="col-md-6">
            <PostList />
          </div>
        </div>
      </div>
    );
  }
}

export default App;

Save the file and go to the http://localhost:3000/

We can add, display, and delete the post if everything is configured correctly.

React Redux Example Tutorial

I have put this code on Github; if you find any errors during the execution of this project, please check out my Github code; it might be helpful to you.

Github Code

That’s it.

2 thoughts on “How to Integrate Redux Inside a React App”

Leave a Comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.