Basic Hooks!

Jake Hyde
Webtips
Published in
6 min readSep 7, 2020

As much as I would love to chat about how cool Dustin Hoffman’s shiny hand toothpick looks, we are not going to chat about the movie Hook. We are here to talk very briefly about React Hooks! As I am learning React, I have come across a lot of code written with Hooks. Since I didn’t understand it at first, here‘s my attempt to explain… Hooks.

Note: If you have questions on React or Hooks, please check out the great documents the React team has put together here and here. I am just going to cover two examples of the basics.

What is a React Hook? Introduced on February 6, 2019, Hooks are a way of creating components without creating a class! Hooks let you manipulate state and other React features of the component lifecycle from functional components.

But why should I care? If you are familiar with building out big components you may find yourself running into difficulty refactoring or you may have paralleled or duplicated logic, or worse heavily nested components referred to as wrapper hell.

https://www.slideshare.net/AikdanaiSidhikosol/react-hooks-101

Hooks help us stay DRY and makes our code more organized and reusable by breaking down reusable code into smaller functions.

Let’s take a look at two examples to explain how hooks are helpful useState and useEffect.

Without Hooks: Below is an example of a stateful component in React without Hooks.

import React from "react"export default class App extends React.Component {

state = {
count: 0,
}
render() {
return (
<div>
<p>You clicked {this.state.count} times</p>
<button onClick={() => this.setState({count: this.state.count + 1}>Click me</button>
</div>
)
}
}

What we are doing here is defining a stateful class component where we initialize the state of the count at 0. After rendering, if the user clicked on the button “Click me”, we will increment the state count by 1. Pretty straight forward right.

With Hooks:

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

As you may have noticed, this looks like a functional component named ‘App’ and you’re right that is because it is! But with the import React, { useState } from "react" line, we are ‘hooking’ into React features and getting access to useState in the ‘App’ functional component. Basically, the point here is that whereas previously you had to create a class to add state, now you can ‘hook’ into the React feature for setting and changing state!

By importing and calling useState, we get two values. A value or variable to manipulate state, and a function to do the action of manipulating of state. In this example, the first value we are using iscountwhich will hold the count that we will increment, just like the oldthis.setState(count: …. The second value is the setCount function that will update thecount by 1. The count is being initialized with zero by passing0 as the only useState argument. In the class component example, we’re using this.state.count + 1 to increment, but with the useState hook, we are using count + 1 . Look how nice and clean that is! So with useState you’ll notice we get const [count, setCount] = useState(0). Or const [firstValue, functionToRun] = useState(initialized state). Check out the very well documented deeper dive here.

This is pretty cool, now let’s look at another hook called the Effect hook with useEffect. “The Effect Hook lets you perform side effects in function components”. What are side effects you may ask? Side effects are parts of the app (some bit of code) that get impacted or executed outside the scope of the function that just got executed. Examples of this are fetching asynchronous data from an API or a function that changes the global variable in a component after execution.

Take a look at this diagram from the man himself Dan Abramov. This is a very good graphical representation of the component lifecycle

https://projects.wojtekmaj.pl/react-lifecycle-methods-diagram/

‘Render phase’ Pure and has no side effects. May be paused, aborted or restarted by React.

‘Commit phase’ Can work with DOM, run side effects, schedule updates.

Check out these comments above ^. What this means is that we want to only run these bits of code that may affect other parts of our application out of scope in the ‘commit phase’. The Effect hook is effectively these lifecycle components: componentDidMount, componentDidUpdate, and componentWillUnmount. What we want to do is utilize these lifecycle methods in a DRYer way with useEffect.

For the fetch example, you would usually add the fetch in the componentDidMount() function. But what if you didn’t? What if you ran this fetch call that has a side effect, in the constructor, for example? How would you see the results after render and seeing the results in the DOM(in HTML)? How would the rest of the lifecycle run and unmount if the side effect of the fetch call is not properly rendered or read when compiling your code? Or what if there is a failed or rejected promise or bad call before mounting and rendering that result? How would you abort that function? As you can imagine this can cause many errors related to the order of mounting and unmounting with regards to the component lifecycle.

Here is the continuation of the example from the React docs.

import React from "react"class Example extends React.Component {state = {
count: 0
};
}
componentDidMount() {
document.title = `You clicked ${this.state.count} times`;
}
componentDidUpdate() {
document.title = `You clicked ${this.state.count} times`;
}

render() {
return (
<div>
<p>You clicked {this.state.count} times</p>
<button onClick={() => this.setState({count:
this.state.count + 1 })}>Click me</button>
</div>
);
}
}

You can see that here the goal is on mount of the component and on update we want to set the current title of the document to the “You clicked some number of times’. When you mount the component, show the initialized state, then when the user clicks on the button, show the updated state. We have to labor over writing two methods to do this.

Enter the Effect hook:

import React, { useState, useEffect } from 'react';function Example() {
const [count, setCount] = useState(0);
useEffect(() => { document.title = `You clicked ${count} times`; });
return (
<div>
<p>You clicked {count} times</p>
<button onClick={() => setCount(count + 1)}>
Click me
</button>
</div>
);
}

As you can see again we import the useEffect hook from react, trade our class for a functional component, and now only have to write 1 function for both lifecycle functions, shortening our code and making it clean! What the Effect hook is doing here, is that it is going to remember the first function to render and subsequently re-render on update. Something important to note is that “By default, it runs both after the first render and after every update.”

So overall these two examples show the very high-level basic benefits for using hooks. It allows us to be more succinct, DRY, and organized with code, and run more efficiently. I hope this was helpful. Here are all the resources:

State Hook

Effect Hook

--

--