Introduction to React Hooks Part 1
Tags: react, javascript, webdev
Published: 2020-02-03 00:20:09


# Prerequisites
 - An understanding of the main concepts of the React library
 - JavaScript fundamentals ([https://www.robinwieruch.de/javascript-fundamentals-react-requirements](https://www.robinwieruch.de/javascript-fundamentals-react-requirements))

# What are React Hooks?
React Hooks allows us to "hook into" React's features like local state-management or lifecycle methods with function components instead of class components. 

# What problems does it solve?
Okay, so if class components can do the same things that Hooks aims to do - setting state, lifecycle methods, context, etc.. then why switch? 

### Large class components can be cumbersome
As our application grows in size, it becomes more and more involved in stateful logic and side effects. Often times, it may contain the same logic spread across lifecycle methods or it may contain some unrelated logic. 

I think the React docs describe it best by saying: 

> For example, components might perform some data fetching in 
> `componentDidMount`  and  `componentDidUpdate`. However, the same 
> `componentDidMount`  method might also contain some unrelated logic
> that sets up event listeners, with cleanup performed in 
> `componentWillUnmount`. Mutually related code that changes together
> gets split apart, but completely unrelated code ends up combined in a
> single method. This makes it too easy to introduce bugs and
> inconsistencies.
> 
> In many cases it’s not possible to break these components into smaller
> ones because the stateful logic is all over the place. It’s also
> difficult to test them. This is one of the reasons many people prefer
> to combine React with a separate state management library. However,
> that often introduces too much abstraction, requires you to jump
> between different files and makes reusing components more difficult.

So Hooks allows us to split components into smaller functions based on what pieces are needed like fetching data.

### Believe it or not, classes are confusing
Let's say you are just starting out and heard about this amazing library called React. Alright, you decide to jump on the bandwagon and learn about it but you stumble upon the dreaded `this` keyword and it's just downright confusing, well, at least it was to me. Then, what about the `constructor(props) {super(props)}` and the fact you have to remember to bind event handlers. 

**Hooks let you use more of React’s features without classes**

> Hooks embrace functions, but without sacrificing the practical spirit of React. Hooks provide access to imperative escape hatches and don’t require you to learn complex functional or reactive programming techniques.

### Reuse of stateful logic
Remember render props or higher-order components, it was a way to share the same functionality across multiple components. However, you have to restructure them as you use them, it becomes quite complicated and your code becomes harder to follow as you progress. So this will also cause "wrapper hell" or when your application has a bunch of nested components.

![enter image description here](https://pbs.twimg.com/media/DoD6dSSVAAAvdkO?format=jpg&name=medium)
([https://twitter.com/GrexQL/status/1045110734550589441?ref_src=twsrc%5Etfw%7Ctwcamp%5Etweetembed%7Ctwterm%5E1045110734550589441&ref_url=https%3A%2F%2Fwww.polidea.com%2Fblog%2Freact-hooks-vs-wrapper-hell-writing-state-in-a-function-with-ease%2F](https://twitter.com/GrexQL/status/1045110734550589441?ref_src=twsrc%5Etfw%7Ctwcamp%5Etweetembed%7Ctwterm%5E1045110734550589441&ref_url=https%3A%2F%2Fwww.polidea.com%2Fblog%2Freact-hooks-vs-wrapper-hell-writing-state-in-a-function-with-ease%2F))

**Hooks allows you to reuse stateful logic without changing your component hierarchy**

# Setting State -  Using the State Hook
This will show you how to setState and update the state in react.

### First let's import it

```jsx
import React, { useState } from 'react'
```

### Let's declare a state variable

We're going to have a side by side comparison with Hooks and Class components.

### Hooks

```jsx
const App = () => {
  const [randomNum, setRandomNum] = useState(0);
}
```

### Classes
   
```jsx
  class App extends Component {
    constructor(props) {
    super(props);
      this.state = {randomNum: 0} 
    } 
    render() {
      . . .
  }
}
```
        
But wait, why is there **randomNum** and **setRandomNum**? The first one, **randomNum** would be your state variable while **setRandomNum** would be a function that updates your state - **randomNum**. 

Putting `set` in front of your updater function is a naming convention and you will likely see this everywhere Hooks is used. 

So, let's break it down: 

```jsx
const [yourStateName, setYourFunctionUpdaterName] = useState(yourDefaultState);
```
In our example, I declared a state variable called **randomNum** and my updater function **setRandomNum**. I then, gave it a default state of 0.

### How do we read the state?

In a class component, it would look something like this:

```jsx 
<h1>{this.state.randomNum}</h1>
```
In Hooks, it would look something like this:

```jsx
<h1>{randomNum}</h1>
```
    
Since in function components, we don't have `this` we can't call it like before with `this.state`. Instead, with Hooks, since it's a variable, we just call it like a variable -  `{randomNum}`. 

### Okay, how do we update the state?

In a class component, we would have to do something like this: 

```jsx 
this.setState({randomNum: newState})
```

In Hooks, we would do somthing like this:

```jsx
setRandomNum(newState)
```
###
### Okay, let's see this in use

Here's an example of setting state in a class component, here we are generating a random number every time the user clicks our button.

```js
<button onClick={() => this.setState({randomNum: Math.floor(Math.random() * 100) + 1})}>Change</button>
```    
Let's recreate this in Hooks

```js
<button onClick={() => setRandomNum(Math.floor(Math.random() * 100) + 1)}>Change</button>
```
With, hooks, since it's a function we just call it like a function. Of course we don't specify what it needs to update -> `setRandomNum` because we already inistalized the state attached to the updater function -> `const [randomNum, setRandomNum] = useState(0)`

And of course, you can have multiple states with different values just like classes:


```jsx
const [age, setAge] = useState(42);
const [fruit, setFruit] = useState('banana');
const [todos, setTodos] = useState([{ text: 'Learn Hooks' }]);
```
### 

# Using the useEffect hook 
The effect hook allows us to perform side effects in function components, so fetching data from an API, setting up a subscription, or changing the DOM in React components are some use cases for this.

Also, useEffect can also be used as a combination of `componentDidMount`, `componentDidUpdate`, and `componentWillUnmount`

So let's take a look at how we go about fetching data in a class component: 

```jsx
componentDidMount() {
  fetch('https://hn.algolia.com/api/v1/search?query=redux')
  .then(response => response.json())
  .then(result => this.setState({data: result.hits});
}
```
Now, let's take a look at data fetching in Hooks: 

### First let's import it

```jsx
import React, {useState, useEffect} from 'react';
```

###

### Now let's see it in action

```jsx
const App = () => {
const [hits, setHits] = useState([]) 
useEffect(()  =>  {
fetch('https://hn.algolia.com/api/v1/search?query=redux')
  .then(response  =>  response.json())
  .then(result  =>  setHits(result.hits));
});
. . .
}
```
By using this Hook, you tell React that your component needs to do something after render. You will pass it a function -> `useEffect( () => {})` and it will call it later after performing the DOM updates. 

It's called inside a component because it enables us to access state variables or any props. 

It also runs after each render so by default it runs after the first render and after every update so that brings us onto our next topic.

If you take a look at our code in this example, it fetches the data and sets the state but **if you actually try to run this you will find yourself in a terrible loop**.

### But why?

Remember when I said that it runs after every update? Well, when we set the state when we get the result that causes it to update and therefore the hook runs again and again and again. 

### And how do I fix this?

We only want to fetch data when the component mounts, so we have to provide an empty array as the second arguement to the effect hook to avoid activating it on component updates.

```jsx
const App = () => {
    const [hits, setHits] = useState([]) 
    useEffect(()  =>  {
    fetch('https://hn.algolia.com/api/v1/search?query=redux')
      .then(response  =>  response.json())
      .then(result  =>  setHits(result.hits));
    }, [] <-- provide an empty array);
. . .
}
```

So now if the variable `hits` changes then the hook will run again. If the array with the variables is empty, the hook doesn't run when updating the component at all, because it doesn't have to watch any variables.

Alright, so there is a lot of other stuff to cover like Custom Hooks, Context, and much more but that should come along in part 2. So stay tuned!

### Before you go, keep in mind these rules 🎉
 
# Important Rules for Hooks 

## Only Call Hooks at the Top Level
Meaning, **don't call them in loops, conditionals, or nested functions**
By following this rule, you ensure:

 - That they are called in the same order each time a component renders
 - It allows React to correctly preserve the state of Hooks between multiple `useState` and `useEffect` calls

## Only Call Hooks from React Functions
**Don’t call Hooks from regular JavaScript functions**
But you can: 

 - Call Hooks from React function components.
 - Call Hooks from custom Hooks ( This will be covered in Part 2)

## ESLint Plugin for enforcing these rules
### How to install

```
npm install eslint-plugin-react-hooks --save-dev
```

```jsx
// Your ESLint configuration
{
  "plugins": [
    // ...
    "react-hooks" 
  ],
  "rules": {
    // ...
    "react-hooks/rules-of-hooks": "error", // Checks rules of Hooks
    "react-hooks/exhaustive-deps": "warn" // Checks effect dependencies
  }
}
```
If you're using Create React App, this is already included! 🥳

Cover Image: https://miro.medium.com/max/3000/1*Ra-gkqfPqbWVhgP3tR-0Cg.png