With the advancement of day-to-day technology, React-Redux had also released hooks with its 7.1.0 version. So this means we also need to update ourselves with latest react practices.
React-Hooks
React Hooks helps us to write less code for the same functionality which we write earlier with class components. If you are new to React-hooks please have a look on my recent article on hooks.
React-hooks - useState, useEffect, useRef, useMemo
vinodchauhan7 ・ Aug 11 '19 ・ 3 min read
In this post, we will convert our simple react-redux application which is currently using class based component approach into hooks with redux.
Here is basic codesandbox
View of Counter Class-Component
import React, { Component } from "react";
import { connect } from "react-redux";
class Counter extends Component {
render() {
return (
<div>
<h3>Count : {this.props.data.count}</h3>
<p>
<button
onClick={() => this.props.dispatch({ type: "INC", value: 1 })}
>
INCREMENT
</button>
<br />
<br />
<button
onClick={() => this.props.dispatch({ type: "DEC", value: 1 })}
>
DECREMENT
</button>
</p>
</div>
); //return ends here
} //render ends here
}
const mapsStateToProps = state => {
return {
data: state
};
};
export default connect(mapsStateToProps)(Counter);
Now lets go step by step :
1) Convert 'Counter' class component to function component.
import React, { Component } from "react";
import { connect } from "react-redux";
const Counter = props => {
return (
<div>
<h3>Count : {props.data.count}</h3>
<p>
<button onClick={() => props.dispatch({ type: "INC", value: 1 })}>
INCREMENT
</button>
<br />
<br />
<button onClick={() => props.dispatch({ type: "DEC", value: 1 })}>
DECREMENT
</button>
</p>
</div>
); //return ends here
};
const mapsStateToProps = state => {
return {
data: state
};
};
export default connect(mapsStateToProps)(Counter);
In above conversion, We have just made functional component and its already code seems very less.
2) Currently we are fetching data from our stores via the mapStateToProps() and
then wrapping our functional component with in connect HOC.
useSelector
useSelector hook help us to read state from stores. We need to import 'useSelector' from 'react-redux'
Import
import { connect, useSelector } from "react-redux";
ReadStatefromStoreViaHook
let data = useSelector(state => state);
UseStateInComponent
<h3>Count : {data.count}</h3>
NoMapsStateToProps
export default connect()(Counter);
3) Till now we successfully read state via useSelector from our store & update our component, now we will look into 'useDispatch' hook to dispatch actions to our store.
useDispatch :
useDispatch help us to dispatch action from component to store.
Import
import { useSelector, useDispatch } from "react-redux";
MakeObject
const dispatch = useDispatch();
UpdateButtonOnClickEvent
<p>
<button onClick={() => dispatch({ type: "INC", value: 1 })}>
INCREMENT
</button>
<br />
<br />
<button onClick={() => dispatch({ type: "DEC", value: 1 })}>
DECREMENT
</button>
</p>
NoHOC_Connect
export default Counter;
Congratulation
You have successfully converted to functional component using react-redux hooks.
Reducer
const initialState = {
count: 0
};
const reducer = (state = initialState, action) => {
let newState = { ...state };
switch (action.type) {
case "INC":
newState.count = newState.count + action.value;
state = { ...newState };
return newState;
case "DEC":
newState.count = newState.count - action.value;
state = { ...newState };
return newState;
default:
return newState;
}
};
export default reducer;
Index.js
import React from "react";
import ReactDOM from "react-dom";
import reducer from "./store/reducer";
import { Provider } from "react-redux";
import { createStore } from "redux";
import Counter from "./counter";
import "./styles.css";
const store = createStore(reducer);
function App() {
return (
<div className="App">
<Counter />
</div>
);
}
const rootElement = document.getElementById("root");
ReactDOM.render(
<Provider store={store}>
<App />
</Provider>,
rootElement
);
If anyone having issue in conversion, please let me know. I will be happy to help you guys.
Top comments (0)