B

­ReactJS with Redux integrations – Solution for state management in react

1) React Component State
2) Redux

Basically, state management is important in any client side javascript framework such as Angular (CLI), Vue or React.
In this topic, I'm going to explain ReactJS 16.0 + version with the react-redux package. Here, I am going to create a sample application which will cover all the basic react-redux concepts including Store, Reducers, Actions and Action creators.

I will set up a sample react app with redux integration steps. For that, I am using a package called 'create-react-app'. This package will create the boilerplate project with zero configuration setup and will provide you simple React application out of the box. First of all, if you are new to react you must know the basic things about the environment set up using Node.JS and NPM a node dependency management tool. If you want to run JavaScript outside of the browser Node.js JavaScript runtime can be very helpful.

NPM (Node package manager) is used to manager dependencies of your application, such as React.js, to your project on the command line.
The first step is to install 
create-react-app package, for installing this package you will need to run the command in your terminal window.

Here we're going to use Visual Studio Code editor, you can go with any editor of your choices like sublime, atom or webstrom. You can find VS Code setup at https://code.visualstudio.com/.

You need to run following command in vs code terminal window, this command will install all the dependencies and the required react packages and will be used to create a working react application.

 

Now that you have installed create-react-app package. You will have to go to your directory path, where you need to create react application and need to run following command as shown below.

 

 

With this changes now you can navigate into your project using the command line and start it with npm start command.

 

 

npm start command will start development server for you and by default, your application will be started on http://localhost:3000/ port. Now that you have setup your react application you will find a structure like below.

 

With this default configuration, you will have your running react app on localhost:3000From the above configuration, we'll delete SVG file and all of it's a reference from App.js file.  So, the app.js file will not have default SVG image and additional content and we are leaving the app.js file with some dummy text in render method. After that, during the next step we need to add a new folder in the src with name “components”. In that, we will add 3 more components as follows “Input.js”, “Item.js”, ”List.js”.

 

1) Input.js

 

import React, { Component } from 'react';
class Input extends Component {
constructor(props) {
super(props);
this.state = {
value: ''};
this.handleChange = this.handleChange.bind(this);
this.handleKeyPress = this.handleKeyPress.bind(this);
}
handleChange(event) {
this.setState({ value: event.target.value });
}
handleKeyPress(e) {
if (e.key === 'Enter') {
this.props.onCreate(this.state.value);
this.setState({
value: ''
});}}
render() {
return (
<input placeholder="Enter your todo !" onKeyPress={this.handleKeyPress} onChange={this.handleChange} value=this.state.value }/> ); } }
export default Input;

2) Item.js

import React, { Component } from 'react';
class Items extends Component {
constructor(props) {
super(props);
this.handleToggle = this.handleToggle.bind(this);
this.handleOnChange = this.handleOnChange.bind(this);
}
handleToggle(event) {
this.setState({ value: event.target.value });
}
handleKeyPress(e) {
if (e.key === 'Enter') {
this.props.onCreate(this.state.value);
this.setState({
value: ''});}}
handleOnChange(e) {
this.props.onClick(this.props.id, e.target.checked);}
render() {
const checkboxId = 'check-' + this.props.id;
return (
<div><input id={checkboxId} type="checkbox" value={this.props.done ? 'false' : 'true'} onChange={this.handleOnChange} checked={this.props.done} /><label htmlFor={checkboxId}>{this.props.text}</label> </div>);}}
export default Items;

3) ListItems.js

import Item from './Item';
import React, { Component } from 'react';
class ListItems extends Component {
render() {
if (this.props.items.length === 0) {
return null;}
return (
<div><p>{this.props.title}</p>
{this.props.items.map(item => (<Item key={item.id} id={item.id} text={item.text} done={item.done} 
onClick={this.props.onItemClick} /> ))}</div> 
);}}
export default ListItems;

 

Finally, after adding those 3 components, we will now add a package called “react-redux” and “redux” in the terminal using the following command.
npm install --save react-redux redux

Once you install this package in your project, it will be used to connect redux with react. Redux is a standalone javascript library for state management.

Now redux has three main core parts which dynamically maintain state in react application which is a store, reducer, actions, dispatchers, and subscribers.
In react application, we have to configure redux using following steps.
1) setup store 2) create reducer function 3) create actions creators 4) create actions types 

1. Setup store:
For setting up redux in react application, we need to modify an index.js file. We need to import createStore function from redux this will create a store in your react application. Also, we need to add another function Provider from 'react-redux' package. Now we need to create store constant variable like below. We need to modify the index.js as following screen-shot.

 

 

With this changes, we have set up our store and we wrapped App component with Provider component and passed store const variable as a property. These will inject redux store in your react application as propsNow we will connect redux store with react application using connect method provided by the react-redux package. We also need to create few functions that will be used to pass property and dispatchers to the current component. Before anything to connect we need to create store folder structure in src directory and need to add 3 new js files inside of in respective folders as given below.

 

 

Actions folder containing actions.js and constants.js which file will store all the constant variables for the entire module. Reducers are the simple actions accepting state and action as a parameter. ES6 features allow you to assign a value to the parameter as you can see in below code.

reducer.js 

import { ADD_TODO, CHECK_TODO, UNCHECK_TODO } from '../actions/constants';
const initialState = { 
items: []
};
const reducer = (state = initialState, action) => {
switch (action.type) {
case ADD_TODO:
const maxId = state.items.reduce(
(maxId, todo) => Math.max(todo.id, maxId),
-1);
return {
...state,
items: state.items.concat({
id: maxId + 1,
done: false,
text: action.text
})};
case CHECK_TODO:
return {
...state,
items: state.items.map(item => ({
id: item.id,
done: item.id === action.id ? true : item.done,
text: item.text
}))};
case UNCHECK_TODO:
return {...state, items: state.items.map(item => ({
id: item.id,done: item.id === action.id ? false : item.done,
text: item.text
})) };
default:
return state;} };
export default reducer;

 

Another js file called constants.js will have const variable in it as given in below code.

 

constants.js

export const ADD_TODO = 'ADD_TODO';
export const CHECK_TODO = 'MARK_TODO_DONE';
export const UNCHECK_TODO = 'MARK_TODO_NOT_DONE';

For consistency and good practice, we will define action id as constants. another file actions.js will hold the action creators that will be dispatch action to reducer function. As you can see below.

import { ADD_TODO, CHECK_TODO, UNCHECK_TODO } from './constants';
export const addTodo = text => ({ type: ADD_TODO, text });
export const markTodoDone = id => ({ type: CHECK_TODO, id });
export const markTodoNotDone = id => ({ type: UNCHECK_TODO, id });

 

 

 

After creating all these files we are going to put them all together for building a central state in redux store. Which we can access in any part of our react application. For we need to change component/app.js file with help connect method and some functions as you can see below.

Now with final changes into the app.js file as you can see below code. We are done with react-redux.

import React, { Component } from 'react';
import './App.css';
import { connect } from 'react-redux';
import * as actionTypes from './store/actions/actions';
import Input from './components/Input';
import List from './components/ListItems';
class App extends Component {
constructor(props) {
super(props);
this.handleCreate = this.handleCreate.bind(this);
this.itemClick = this.itemClick.bind(this);
}
handleCreate = text => {
this.props.onAddNote(text);
};
itemClick = (id, done) => {
if (done) {
this.props.onCheckToDo(id);
} else { this.props.onUncheckToDo(id); } };
render() { return (<div>
<Input onCreate={this.handleCreate} /><List title="To do" items={this.props.items.filter(item => !item.done)} onItemClick={this.itemClick}/> 
<List title="Done" items={this.props.items.filter(item => item.done)}
onItemClick={this.itemClick} />
</div>
);}}
const mapStateToProps = state => {
return {
items: state.items
};};
const mapDispatchToProps = dispatch => {
return {
onAddNote: text => dispatch(actionTypes.addTodo(text)),
onCheckToDo: id => dispatch(actionTypes.checkTodo(id)),
onUncheckToDo: id => dispatch(actionTypes.uncheckTodo(id))
};};
export default connect( mapStateToProps,mapDispatchToProps)(App);

Tags:
  • React readux

Comments

Leave a Reply