How To Connect React and Redux With Example

In this tutorial, we will see How To Connect React and Redux With Example. For this simple demo, we will not be going to use any backend; we will do that in the next tutorial. We keep this example very simple and make it work at the client side. We create a simple post and display it, but we are going to manage it via Redux store. We can create and delete the post, and our store will handle all the data. We use Bootstrap 4 for the frontend.

If you are new to Redux then please check out my following article.

Read This First: Redux Tutorial With Example From Scratch

Also, you can take the following course.

If you want to learn more about React.js then check out this React 16 – The Complete Guide (incl. React Router 4 & Redux) Guide. It has a very brief intro about React and Redux.

React 16 – The Complete Guide (incl. React Router 4 & Redux) check out

How To Connect React and Redux With Example

The API for the React Redux bindings is straightforward: a Provider component that makes our store accessible throughout our app and a connect function that creates container components that can read the state from the store and dispatch actions. First, we install the React.js and right now the latest version of React.js is 16.4.1.

Step 1: Install React.js.

Type the following command.

npm install -g create-react-app create-react-app postreactredux

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 the 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 NewPost component.

If use react and redux together then separation of concern is there. Means, there are two types of components.

Dumb Components Smart Component(Containers)

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

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

Now, inside src folder, create 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.

title body

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

Okay, now we need to import this NewPost.js file inside 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 by the following command.

Step 4: Create the actions.

Now, inside src folder, create three more folders, and their names are following.

containers reducers actions

Now, first inside 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 add the 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 state of the store.

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

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

Action type Payload

As we know for our demo, we have two actions, so create one file inside src >> actions folder called index.js.

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

npm install uuid --save # or yarn add uuid

Now, write the following code inside 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 title and body as a parameter and return an object.

We add an extra payload called an id so that we can render different posts and delete according to their IDs.

Step 5: Create the rootReducer and postReducer.

Now, inside 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 is matched with fired action, then it will modify the store and change the current state.

Now, create an index.js file inside reducers folder. 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 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 NewPost.js file, and that is a CreatePost.js file.

Now, we import this CreatePost.js file inside 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 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 be able to track the state inside the store. You can modify the state through actions.

Step 8: Display the Post.

Create a component inside components folder called Post.js and write the following code inside it.

Post.js component is responsible for rendering out our 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 data of title, body, and id and render it.

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

Now, inside 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. When the new post is added, this component is notified because this component is directly connected to the store.

If the delete action is triggered, then it will filter out that post and display the remaining posts.

Now, a final thing is import this PostList.js component inside 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/

If everything configured correctly then we can be able to add, display, and delete the post.

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

Github Code

Steps To Use Github Code.

Clone the repo. Go to the project folder and install dependencies: npm install Start the dev server by this command: yarn start

Finally, How To Connect React and Redux With Example is over. Thanks.