Working with React Hooks

A quick overview for working with hooks

David Minkovski
3 min readAug 16, 2021

--

React hooks were introduced in February 2019 starting with React 16.8 to improve the readability and performance of the code.
Before Hooks, there were basically two types of React components:

Classes that would handle a state
Functions that are fully defined by their props

A common architecture was to build complex container components with classes and simple presentational components with pure functions.

So what are React Hooks?

Container components process state and handle server requests, which we can call “side effects”. The state is then passed on to the child components through properties.
But as the code grows, functional components tend to be converted into container components.
Transforming a functional component into one with more logic and state is not that complex, but it is definitely time-consuming. In addition, the line between container and presentation component is becoming blurred.
Hooks can do both, so the resulting code is much more consistent and has all of the benefits at the same time.
Here is an example of adding local state to a small component.

import React, {useState} from "react";
const Counter = () => {
const [count, setCount] = useState(0); return (
<div>
<p>You clicked {count} times!</p>
<button onClick={()=> setCount(count+1)}>Click me!</button>
</div>
)
}
export default Counter;

useEffect — Simply effectful

The useEffect hook can be more difficult to understand at first, especially if you think too much about old React lifecycles.
As mentioned earlier, a side effect is an action the component performs after it has been rendered. Especially when it comes to manipulating the state.

A practical example: Suppose you have a component that displays a list of products for a category. So once your component is rendered, you want to make an API call. If the category changes later (e.g. if the user switches from the shoe category to the pants category), you want to call the API again.
In the old class component, our example would look like this:

class ProductList extends React.Component {
componentDidMount() {
this.fetchProducts();
}
componentDidUpdate(prevProps) {
if (prevProps.categoryId !== this.props.categoryId) {
this.fetchProducts();
}
}
getProducts() {
// API CAll with new category ID
}
}

How does this translate to hooks?

const ProductList = (props) => {
const fetchProducts = () => {};
useEffect(() => {
fetchProducts();
}, [props.categoryId]);
};

This does look a lot cleaner! We define an effect that gets a function that is called after rendering and then calls another function.
Fortunately, useEffect accepts an array of dependencies. This means that we can specify on which state or property change we want to trigger the effect.

How does the “didMount” Hook implementation work?

The answer ist quite easy. We leave the dependency array empty.
When adding a dependency array, the effect is called whenever one of the values ​​in the array changes. If the array does not contain any element, it is only called after the first rendering.
If we want the effect to run after each rendering, we can leave out the dependency array entirely. However, this can lead to performance issues and should be implemented with caution.

Summary

In this article we got a little insight into the world of Hooks.
They are designed to solve a big React problem — how to make logic reusable.
Hooks are a great alternative to higher-order components.
In addition, hooks provide a way to map the behavior of classes to functional components. While this is always a matter of personal opinion, I’d say Hooks will stay within React.
Not because of a “hype” but because they are simply better!

Curious about more?

My newsletter is a burst of tech inspiration, problem-solving hacks, and entrepreneurial spirit.
Subscribe for your weekly dose of innovation and mind-freeing insights:
https://davidthetechie.substack.com/

--

--