Friday, June 12, 2020

Redux with ReactJs example for using state container

Redux and React are two different JavaScript language. React is more towards the view part of MVC and redux is third party library that handle state of the application globally.
So let first create a simple react application where in we will have local state which we will increase or decrease the local state with click on Increment and Decrement button
Step 1:- lets first create a new reactJS application using below command
npx create-react-app my-app
Once the application is installed execute the below command and check the ui.
cd my-app
npm start
Image1
Step 2:- We are going to create a simple reactjs application having a counter as number and having two button 1- for increment and 2- decrement
Please find the below code for the same.
import React from 'react'
class Simplereactredux extends React.Component {
constructor(props) {
super(props)

this.state = {
counter: 1

}
this.increment = this.increment.bind(this);
this.decrement = this.decrement.bind(this);
}

increment() {
this.setState({ counter: this.state.counter + 1 })
}

decrement() {
this.setState({ counter: this.state.counter - 1 })
}

render() {
return (
<div>
<h1>This is parent component</h1>
<label > Counter: <span>{this.state.counter}</span> </label>
<br></br>
<button onClick={this.increment}>Increment</button>
<button onClick={this.decrement}>Decrement</button>
</div >
)
}
}

export default Simplereactredux

Image2
Now in above example we had used the normal state i.e. local state defined in class to do the increment and decrement operations.
Now lets move to take this local state to our Redux central state container so that it will be available for all the component to access direclty who had subscribe themself to this store and get notified when there is change in the state with the help of subscriber.

For doing this we will need to packages to be installed in our application
1- redux :- This package will provide us the environment to create a central store where we can keep the global state of the application which can be modified by firing the event or action through reducer.
2- react-redux :- As redux is external thrid party predictable state container management tool for interacting it with the redux we need to create a bridge that connect this two different packages.

Lets now install both of them using below commands
npm install redux --save
npm install react-redux --save
and check your package.json having this two package installed init.

Now as we know in Redux we have three main parts
1- Store
2- Reducer
3- Action
First we will create a reducer which is responsible to perform action as per the action_type on the global state store in the stores.
I am creating a folder inside src folder called as store and will create reducer.js
const intialState = {
counter: 1
}
const reducer = (state = intialState, action) => {
const newState = { ...state }
return newState
}

export default reducer

Now as we are going to use the store as global we need to inject it into the react at the top level or highest level of top level component which is our app.js where we inject out </simplereactredux> component. The package which we will use to inject the global store is Provider from react-redux.
//1- Need to import Provider packages from react-redux to inject the global store for our application.
import { Provider } from 'redux-react'
<Provider>
<Simplereactredux></Simplereactredux>
</Provider>

Now lets create the store using createStore packages of redux
//2- Create the store now that can be used by the react using redux
import myreducer from './store/reducer'
const store = createStore(myreducer)
and finally give this store to our entire React application as shown below
<Provider store={store}>
<Simplereactredux></Simplereactredux>
</Provider>
Now the next step would be to comment all the code that we were using to store the data a local state and need to plugin our store in our component so that we can use the global stores. This need to be done for all the components to map with stores for using this global stores. i.e. mapping the props.
Along with this also note we need to subscribe our react application to redux so that whenever there is a changes in the global state in redux our react application can be notified and also we must be able to fire/dispatch an action/event with action_type from react to the redux to modify the global state from redux.
In container/ReactJs applcation we use either local state or props. As now we are going to use the global state of redux only the option left for us is to use the props concept to get in touch with the Redux from reactjs application/containers.
for this we have follwing fucntion mapDispatchToProps
mapDispatchToProps = (dispatch) => {
return {
increment: () => dispatch({ type: 'action_type_increment' }),
decrement: () => dispatch({ type: 'action_type_decrement' }),
}
}
As shown above in this function we are mapping our button function with this props and further from this method we deliver/fire/dispacth event with action_type i.e. action_type_increment or action_type_decrement.
Now the question is where this action type will go ..yes you are right as per the Redux when ever the action is dispatched/fire from the application it will go to the reducer and depending on the action_type it will perform respective operation on global state.
Additional we also want the subscription of our reactjs application so that when ever there is change in the global state that state can be accessed/refresh at our container or pages. For that also we will need to map it with the props so that is automatically available for us using funtion mapStateToProps

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

Finally we need to contact our container/reactjs application to store and that is done using connect
//below package is used to connect react application or react component with Redux.
import { connect } from 'react-redux'
Use this connect as HOC as shown below
export default connect( mapStateToProps , mapDispatchToProps) (Simplereactredux)

whole code
import React from 'react'
//below package is used to connect react application or react component with Redux.
import { connect } from 'react-redux'
class Simplereactredux extends React.Component {
constructor(props) {
super(props)
this.state = {
// counter: 1
}
/* this.increment = this.increment.bind(this);
this.decrement = this.decrement.bind(this); */
}
/* increment() {
this.setState({ counter: this.state.counter + 1 })
}

decrement() {
this.setState({ counter: this.state.counter - 1 })
}
*/

render() {
return (
<div>
<h1>This is parent component</h1>
<label > Counter: <span>{this.props.counter}</span> </label>
<br></br>
<button onClick={this.props.increment}>Increment</button>
<button onClick={this.props.decrement}>Decrement</button>
</div >
)
}

}
const mapStateToProps = (state) => {
return {
counter: state.counter
}
}
const mapDispatchToProps = (dispatch) => {
return {
increment: () => dispatch({ type: "action_type_increment" }),
decrement: () => dispatch({ type: "action_type_decrement" }),
}
}
// use the connect HOC to connect reactjs component to redux
export default connect(mapStateToProps, mapDispatchToProps)(Simplereactredux)
Image3
Note: You can download the source code from https://github.com/shdhumale/simplereactreduxexample

No comments: