Les hooks React expliqués!: useState (1/8)
Tags: react, hooks, javascript, french
Published: 2021-05-23 11:38:23

Les articles de la série:
1. 👉🏾 [useState](https://bit.ly/343SiMS)
2. [useEffect](#)
3. [useReducer](#)
4. [useContext](#)
5. [useCallback](#)
6. [useRef](#)
7. [useMemo](#)
8. [useLayoutEffect](#)


Salut à tous!
Cet article est le premier d'une série de 8 consacrés aux **hooks** en React. Il s'agira de présenter chacun des hooks (ou presque), leur utilité ainsi qu'un ou deux cas d'utilisation.
L'objectif est essentiellement de faciliter leur prise en main. Par conséquent, ces articles s'adresse en premier lieu à toutes personne ayant une connaissance basique de React.

Sur ce, en avant la musique...🎶 😎

# C'est quoi les hooks?
Les hooks sont simplement un ensemble de fonctions permettant de reproduire les fonctionnalités offertes par les composants basés sur les classes (**class-based components**) dans les composants basés sur les fonctions (**fonctional components**). Elles sont disponibles depuis la version 16.8 de React.

Par convention, leur noms sont sous la forme _useXXX_. Elles sont donc facilement reconnaissables 🙂. 
Les hooks les plus populaires sont **useState**, **useEffect**, **useCallback**, pour ne citer que ceux là.

Dans la suite de ce premier article, nous explorerons plus en détails le hook **useState**.

# Pourquoi utiliser les hooks?
Les hooks permettent d'exploiter pleinement les composants basés sur des fonctions. Alors la bonne question serait plutôt: **Pourquoi utiliser les composants basés sur des fonctions?**

Pour faire simple, ils nous permettent d'écrire des composants moins verbeux, plus simple à lire, comprendre et à maintenir. 

Cependant, le but de cette article n'étant pas de vous présenter l'utilité des composants basés sur des fonctions, j'invite les plus curieux á en savoir plus en allant par **[ici](https://fr.reactjs.org/docs/hooks-intro.html#motivation)**.

# A quoi sert useState?
Pour ceux qui utilisent React depuis les versions <16.8, **useState** est l'équivalent de _this.state_ et _this.setState_. C'est le "hook d'état" qui permet de gérer un état dans un composant basé sur une fonction.


# Comment utiliser useState?
Assez parlé, un exemple s'impose 😌.

#### Avec un composant basé sur une classe
```jsx
import { Component }  from 'react'

class MyComponent extends Component {
  constructor(props) {
      super(props)
      this.state = {
          count: 0
      }
  }

  handleClick() {
    this.setState({count: this.state.count + 1})
  }

  render() {
    return (
      <div>
        <p>Vous avez cliqué {this.state.count} fois</p>
        <button onClick={this.handleClick}>
          Cliquez ici
        </button>
      </div>
    )
  }
}
``` 

#### Equivalent avec un composant basé sur une fonction
```jsx
import {useState} from 'react'

const MyComponent = () => {
  const [count, setCount] = useState(0)

  const handleClick = () => {
    setCount(count + 1)
  }
  
  return (
    <div>
      <p>Vous avez cliqué {this.state.count} fois</p>
      <button onClick={this.handleClick}>
        Cliquez ici
      </button>
    </div>
  )
}
```

Avouez qu'avec le hook c'est beaucoup moins verbeux 😁.

Décortiquons tout ça!

#### Création d'une variable d'état
```javascript
const [count, setCount] = useState(0)
```
La fonction **useState** prend en paramètre l'état initial (la valeur par défaut) et retourne un tuple contenant l'état actuel et une fonction permettant de le modifier. **Attention l'ordre est important**.
Ci-dessous, la signature de la fonction **useState**:
```javascript
(initialState) => [state, setState]
```

Par convention, le nom de la fonction permettant de modifier l'état est sous la forme `set<StateName>` afin de facilement savoir à quoi elle sert et quel état elle modifie.

#### Modification d'un état
```javascript
setCount(count + 1)
```
Pour modifier l'état, on appelle la fonction renvoyée par **useState**, dans notre cas _setCount_, en lui passant en paramètre la nouvelle valeur à attribuer à l'état.
Ci-dessous, la signature de la fonction renvoyée par **useState**:
```javascript
(newState) => void
```

##### ⚠️ Attention !!! Il ne faut surtout pas modifier l'état comme ceci:
```javascript
count = count + 1
```
⛔️⛔️⛔️⛔️ Mauvais Mauvais Mauvais et... Mauvais 🙅🏾‍♂️

En mettant à jour l'état de cette manière, React ne saura pas que votre état a changé. **Il n'actualisera donc pas le rendu du composant!**.

Vous pouvez utiliser autant de variable d'état que vous le souhaitez dans un composant.
```jsx
import {useState} from 'react'

const MyComponent = () => {
  const [count, setCount] = useState(0)
  const [age, setAge] = useState(30)
  const [city, setCity] = useState('Abidjan')
  const [lunch, setLunch] = useState('🍔')

  ...
}
```

#### 💡 Petite astuce de pro
La fonction renvoyée par **useState** a une deuxième signature:
```javascript
((prevState) => newState ) => void
```
Cela signifie qu'au lieu de lui passer directement le nouvel état, vous pouvez lui donner en paramètre une fonction qui prend elle-même en paramètre l'état actuel et renvoie le nouvel état.

Hum... pas clair 🙃? Un petit exemple s'impose donc.
```javascript
setCount((previousState) => previousState + 1)
```
Ici, notre fonction _setCount_ reçoit en paramètre la fonction _(previousState) => previousState + 1_. La variable _previousState_ représente dans cette fonction l'état courant. Autrement dit _previousState === count_. Puis, elle renvoie à _setCount_ l'état courant incrémenté _previousState + 1_. 😊

Cette méthode est très utile lorsque vous avez des états plus complexes comme des objets et que vous souhaitez seulement mettre à jour une partie de l'état.

```javaScript
// Déclaration de l'état
const [person, setPerson] = useState({firstName: 'Martial', lastName: 'Anouman', age: '🤐'})

...
// Mise á jour en réaction à un évènement
setPerson((previousState) => {...previousState, firstName: 'Martial G.'})
...

console.log(person)
```
```shell
{age: '🤐', firstName: 'Martial G.', lastName: 'Anouman'}
```

Voila, c'est tout pour le hook **useState** 😊.

J'espère que cet article vous a plu et aidé dans votre prise en main de ce hook. 
Rendez-vous au prochain article de la série sur le hook **[useEffect](#)**(en cours).

Happy coding! 🤓