How to implement redux in React.js
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
- Overview of redux example
- Setup react application
- Install redux dependencies
- Project structure
- Create action types
- Create actions
- Create reducers
- Combine multiple reducers
- Create store
- Make redux store available to the application
- Connect component with the store
- 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 Components3. Install redux dependencies
In order to implement redux, we have to install redux dependencies. Run the command below.
1 | 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.
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
1 2 3 4 5 6 7 8 9 10 | // 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
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | 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
1 2 3 4 5 6 7 8 9 10 11 12 13 | 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
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 | 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
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | 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
1 2 3 4 5 6 7 8 9 10 11 | 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
1 2 3 4 | 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
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | 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
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | 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
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 | 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
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 | 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.
That’s it for today. In the next article, we will show you the API call with redux.
Thank you for reading. Happy Coding!