I'm going to convince you using React Hooks
Chandelier Axel
Posted on October 16, 2020
(If you are not using them yet, of course).
Quick intro
Lately, I've been working on a React app as part of my job. We are working with the usual React + Redux, with the old "class" way (which are still completely valid, don't get me wrong). But you know, hooks have been around for quite a while, and they are amazing. Let me show you why they are, and give me a chance to convince you using them.
Redux
If you have worked with Redux before, you know the drill:
- Create the store
- Wrap your application within the store
- Connect the component with the HOC (Higher-Order-Component)
- Create the mapStateToProps and mapDispatchToProps functions and applied theses to the connect ...
Pretty basic things that we do everyday, you may even have some VSC snippets to help you out.
State
Let's leave Redux for a second. How would you declare a state ?
- Create your component
- Call the constructor and the super
- Create your this.state variable and fill it with values
~ Wait, in a real world exemple, there is more ...
~ You're right, let's add some lifecycles.
Lifecycles
In every real apps, you will have to gather some datas from your API endpoints. The best place to do so is within the ComponentDidMount. Sometimes, you even need to apply things on certains updates, it's where ComponentDidUpdate is coming handy. And of course you need to clean your subscriptions into a ComponentWillUnmount ...
A lot of things to remember, right ? And a lot of methods to write.
~ What if I can tell you that you can transform the 10+ lines declaration, into a 3 lines one ?
~ But, how ?!
With React Hooks feature, and this is how I'm going to convince you to give them a try.
Regular Class style exemple
Let's put everything we talked about inside this component ...
import React from 'react';
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
// State ..
user: {},
};
}
componentDidMount() {
// Fetch API endpoint
}
componentDidUpdate(prevProps, prevState) {
// Apply effect based on changes ..
}
componentWillUnmount() {
// Cancel subscriptions ..
}
render() {
return <div>// Your app tree</div>;
}
}
const mapStateToProps = (state) => {
return {
// Return some element from your state ..
};
};
const mapDispatchToProps = (dispatch) => {
return {
//Return some functions that dispatch for you in the store ..
};
};
export default connect(mapStateToProps, mapDispatchToProps)(App);
As you can see, without any logic specific code and JSX, the minimum required amount of code start to be substantial.
Functionnal Component exemple
Now the fun part, let's rewrite everything using some Hooks. Don't worry, we will do it step-by-step.
First, let's initialze your state:
import React, { useState } from 'react';
const App = () => {
const [user, setUser] = useState({});
return <div>// Your app ..</div>;
};
export default App;
Let's recap what is going on here. We use a React Hook called useState() which return a value, and a method to update this value. We also use the nice destructration synthax to get a super nice one liner.
(More informations on the useState here).
Next, let's add our lifecycles:
import React, { useState, useEffect } from 'react';
const App = () => {
const [user, setUser] = useState({});
useEffect(() => {
// Equivalent of componentDidUpdate
return () => // Equivalent of componentWillUnmount
}, []); // Equivalent of componentDidUpdate.
// It's an array of dependencies, add values there,
// and React will re execute the useEffect whenever one of value changes
return (
<div>
// Your app ..
</div>
)};
export default App;
Amazing, isnt it ? You can find more more infos here. But basically, React will always execute what is inside he useEffect on the first render, and will watch the value passed into the array to re-run the effect again. You'll return what you want to execute when the component unmount.
And last but not least, let's use Redux in there :
import React, { useState, useEffect } from 'react';
import { useSelector, useDispatch } from 'react-redux';
const App = () => {
const [user, setUser] = useState({});
const dispatch = useDispatch(); // Give access to the dispatch function
const foo = useSelector(state => state.foo); // Recover the value from the store
useEffect(() => {
// Equivalent of componentDidUpdate
return () => // Equivalent of componentWillUnmount
}, []); // Equivalent of componentDidUpdate. It's an array of dependencies, add values there, and React will re execture the useEffect whenever one of value changes
return (
<div>
// Your app ..
</div>
)};
export default App;
The code is pretty straightforward, buy it's only some very basic usages, you can gather more infos here. But bascially, you now have access to the dispatch function, and to whatever value you want without having to mapDispatch and mapState. Without even the connect, and our component is now connected implicitely.
Conclusion
Well, nothing to conclude on, really. But take a second, and compare both code snippets. The result is stunning, you saved so much code for doing the exact same thing.
I'll link you the react official documentation here, and you can scroll down to a youtube video that does an amazing convertion from class to hooks.
Now, tell me, are you convinced to give them a try ?
You can find the original article on the Othrys website and you can follow my Twitter or tag me here to discuss about this article.
Have a nice day.
Posted on October 16, 2020
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.