# Quick Recap : Hooks

## Hooks useState & useEffect

{% embed url="https://codesandbox.io/s/white-paper-2xr4u" %}

{% embed url="https://codesandbox.io/s/react-hooks-usestate-and-useeffect-r666o" %}

Hooks with HTML Form

{% embed url="https://codesandbox.io/s/react-hooks-usestate-and-useeffect-t13xd" %}

So the theory in React is that a piece of UI can “react” in response to a state change. The basic form for expressing this flow was an ES6 class up until now. Consider the following example, an ES6 class extending from React.Component, with an internal state:

```
import React, { Component } from "react";

export default class Button extends Component {
  constructor() {
    super();
    this.state = { buttonText: "Click me, please" };
    this.handleClick = this.handleClick.bind(this);
  }

  handleClick() {
    this.setState(() => {
      return { buttonText: "Thanks, been clicked!" };
    });
  }

  render() {
    const { buttonText } = this.state;
    return <button onClick={this.handleClick}>{buttonText}</button>;
  }
}
```

As you can see from the code above the component’s internal state gets mutated by **setState** when clicking the button. The text’s button in turns reacts to this change and gets the updated text.

A more **concise version of the component** can be expressed by removing the constructor thanks to [**class fields**](https://developers.google.com/web/updates/2018/12/class-fields):

```
import React, { Component } from "react";

export default class Button extends Component {
  state = { buttonText: "Click me, please" };

  handleClick = () => {
    this.setState(() => {
      return { buttonText: "Thanks, been clicked!" };
    });
  };

  render() {
    const { buttonText } = this.state;
    return <button onClick={this.handleClick}>{buttonText}</button>;
  }
}
```

So, in the beginning there was setState (and still it will be). But keep calm. The style above is perfectly fine and **ES6 classes in React won’t go away anytime soon**.

But **now with React hooks it’s possible to express the flow internal state change**&#x20;

### **UI reaction without using an ES6 class**.

So what options do we have for managing the internal state in React now that **setState and classes are not a need anymore**?

Enter the **first and most important React hook: useState**. **useState is a function** exposed by the react package. You will import that function at the top of your files as

```
import React, { useState } from "react";
```

1. **By importing useState in your code you’re signaling the intent to hold some kind of state inside your React component**. And **more important, that React component shouldn’t be an ES6 class anymore. It can be a pure and simple JavaScript function**. This is the most appealing thing of this hooks story.

After importing useState **you’ll pick an array containing two variables out of useState**, and the code should go inside your React component:

```
const [buttonText, setButtonText] = useState("Click me, please");
```

1. Confused by this syntax? It’s [ES6 de-structuring](http://exploringjs.com/es6/ch_destructuring.html). The names above can be anything you want, it doesn’t matter for React. Anyway **I advise using descriptive and meaningful variable names** depending on the state’s purpose.

The **argument passed to useState is the actual starting state**, the data that will be subject to changes. useState returns for you two bindings:

* the actual value for the state
* the state updater function for said state

So the previous example, a button component, with hooks becomes:

```
import React, { useState } from "react";

export default function Button() {
 const [buttonText, setButtonText] = useState("Click me, please");

 return (
 <button onClick={() => setButtonText("Thanks, been clicked!")}>
 {buttonText}
 </button>
 );
}
```

For calling the setButtonText state updater inside the onClick handler you can use an inline arrow function. But if you prefer using a regular function you can do:

```
import React, { useState } from "react";

export default function Button() {
 const [buttonText, setButtonText] = useState("Click me, please");

 function handleClick() {
 return setButtonText("Thanks, been clicked!");
 }

 return <button onClick={handleClick}>{buttonText}</button>;
}
```

Must be honest, I fancy regular functions more than arrow functions, unless I have specific requirements. Readability improves a lot. Also, when I write code I think always of the next developer that will mantain that code. And my code should be readable.

React hooks, that’s it! I could end this post here but not before showing you **how to fetch data with hooks**.

#### Data fetching in React **functional Components**

Do you remember the old days of componentDidMount? You would slap fetch(url) in componentDidMount and call it a day. Here’s how to fetch an array of data from an API for rendering out a nice list:

```
import React, { Component } from "react";

export default class DataLoader extends Component {
  state = { data: [] };

  componentDidMount() {
    fetch("http://localhost:3001/links/")
      .then(response => response.json())
      .then(data =>
        this.setState(() => {
          return { data };
        })
      );
  }
  render() {
    return (
      <div>
        <ul>
          {this.state.data.map(el => (
            <li key={el.id}>{el.title}</li>
          ))}
        </ul>
      </div>
    );
  }
}
```

I thought data fetching with React hooks shouldn’t look so different from useState. A quick glance at the documentation gave me an hint: **useEffect could be the right tool for the job**.

I read: “**useEffect serves the same purpose as componentDidMount, componentDidUpdate, and componentWillUnmount in React classes, but unified into a single API**”

Bingo! It’s amazing, isn’t it? With this knowledge in hand I refactored the first version of Data-loader for using useEffect. The **component becomes a function and fetch gets called inside useEffect**. Moreover, **instead of calling this.setState I can use setData (an arbitrary function extracted from useState)**:

```
import React, { useState, useEffect } from "react";

export default function DataLoader() {
  const [data, setData] = useState([]);

  useEffect(() => {
    fetch("http://localhost:3001/links/")
      .then(response => response.json())
      .then(data => setData(data));
  });
  return (
    <div>
      <ul>
        {data.map(el => (
          <li key={el.id}>{el.title}</li>
        ))}
      </ul>
    </div>
  );
}
```

“**useEffect serves the same purpose as componentDidMount, componentDidUpdate, and componentWillUnmount**“

componentDidUpdate! **componentDidUpdate is a lifecycle method running every time a component gets new props, or a state change happens**.

That’s the trick. **If you call useEffect like I did you would see an infinite loop. And for solving this “bug” you would need to pass an empty array as a second argument to useEffect**:

```
 useEffect(() => {
 fetch("http://localhost:3001/links/")
 .then(response => response.json())
 .then(data => setData(data));
 }, []); // << super important array
```

