---
# System prepended metadata

title: 'Exercices: Les hooks'

---

# Exercices: Les hooks

:::info
Tous ces exercices devront être réalisé avec la méthode d'écriture de composant fonctionnel afin de pouvoir utiliser les hooks.
:::

::: warning
SI VOUS ÊTES EN AVANCE VOUS POUVEZ REGARDER CETTE VIDEO:

https://www.youtube.com/watch?v=ilqxZiXnwD8

:::

### Exercice 1: useState

#### 1.1  ---

Créez un composant `CustomInput` qui vous permettra d'écrire un text à l'intérieur. Utilisez le hook `useState` pour gérer l'input et `TextInput` de react-native.
Essayez d'y ajouter un peu de style 

Nommez votre état `keyword`


######  `Exemple:`
![](https://i.imgur.com/kwFQlLD.png)


---

#### 1.2  --- Multiple state variable

À l'exercice précédent, rajoutez une nouvelle variable d'état `fontSize` toujours via le hook `useState`.
Rajoutez au champ précédent deux boutons pour pouvoir augmenter ou diminuer la taille de la police.
######  `Exemple:`
![](https://i.imgur.com/bsNW9Fe.gif)

---
#### 1.3 --- Object state variable

Regroupez dans cet exercice les variables d'état qui ont servi à votre CustomInput en un seul objet et donc un seul `useState`.
Pour changer l'état de chaque attribut de cet objet créez une fonction `handleSetState` qui prendra deux paramètre, la "clé" *(qui sera le nom à proprement parlé de votre état ex: 'keyword', 'fontSize')* et une valeur.

Utilisez ensuite cette fonction `handleSetState` pour changer votre état au lieu de setState

######  `Exemple:`
``` javascript
 const [state, setState] = useState({
    keyword: '',
    fontSize: 12,
  });
  
 handleSetState('keyword', 'blabla') 
  
```

:::  info
Il est possible de changer le champ d'un objet lorsque l'on connait son nom en `String`.

Imaginons que je veux changer `fontSize`dans mon objet ci-dessus.
J'aurais quelque chose comme: 
```
state['fontSize'] = ...
```
ou bien
```
const value = 'fontSize'
state[value] = ...
```

Ceci devrait vous aider à généraliser le tout.
:::

<br/>

### Exercice 2: useEffect

:::warning

Si vous êtes en avance

https://www.youtube.com/watch?v=vNLwY2UlbQg
:::

#### 2.1  ---

Utilisez simplement un effet dans votre composant précédent via le hook `useEffect` pour afficher en console le `keyword` de votre input.

#### 2.2 ---

Dans l'exercice précédent vous avez peut être rémarqué que lorsque l'état de votre composant change, peut importe si c'est la `fontSize`ou le `keyword`, celui-ci est toujours affiché en console.

Si vous ne l'avez pas remarqué testez avant la suite, **si vous ne voyez pas ce fonctionnement, appelez moi**.

Faites en sorte que l'effet se lance uniquement lorsque `keyword` change.

::: spoiler
 > Tu n'es pas allé cherché bien loin....
 >
 > Utilisez les dépendances du useEffect, rappelez vous.
:::

#### 2.3 ---

Plusieurs choses à faire dans cet exercice:
* Créez un nouvel état `error` qui sera un message d'erreur en dessous du champ de texte.
* Affichez ce message si `error` n'est pas vide.

Ensuite, vous allez créer un effet qui set l'error **une seconde après** que l'utilisateur ait terminé de taper dans l'input et que ce text tapé est différent d'un text choisi au préalable.

* L'erreur affichée doit être un chiffre aléatoire, utilisez cette formule: `Math.floor(Math.random() * 10)`
* Choisissez le text que vous voulez pour comparer. Dans l'exemple ci-dessous le mien est `"Bonsoir"`
* Créez un dernier état `time` qui vous servira pour savoir si l'utilisateur à terminé de taper.

:::    info
**Info**

Comment faire pour savoir si l'utilisateur a terminé de taper sur l'input ?

Faite usage des fonctions JavaScript `clearTimeout` et `setTimeout`.
Chaque fois que l'input change, il faut "clear" et "set" le timer. Lorsque l'utilisateur aura terminé de taper le `setTimeout` finira par s'éxécuter.
:::

:::spoiler
T'as pas cherché...
``` javascript
  useEffect(() => {
      clearTimeout(time);
      time = setTimeout(() => {
        console.log("Hello");
    }, 1000)
  }, [value]);
```
:::

###### `Example:`

![](https://i.imgur.com/hTi5sZV.gif)

<br/>

### Exercice 3: Custom Hook

#### 3.1 ---

:::info
Avant d'entrer dans cet exercice je vous conseille de vous raffraîchir la mémoire sur comment écrire et ce qu'est un hook personnalisé soit via l'internet mondial soit avec la vidéo disponible ici (https://youtu.be/s8CwWL7U2hk?t=675)
:::

Créez un hook personnalisé qui:
* Retournera la valeur de votre état et sa fonction pour le changer
* Reprendra la logique du timer pour détecter quand un utilisateur à terminer de tapper.
Ce hook aura la signature suivante :
``` javascript
const useMyTextInput = (initialValue, callback = null) => {...}
```
* `initialValue` sera la valeur de base de votre input
* `callback` sera la fonction que vous voulez éxecuter comme effet après que l'utilisateur ait terminé de taper.

::: warning
`callback = null` signifie que si aucune fonction n'est passé dans ce paramètre, celui-ci sera `null` par défault. N'oubliez donc pas de gérer ce cas !
:::

Ce hook devra retourner une pair contenant la valeur, et une fonction `handleChange`.
Il doit implémenter la logique de l'effet réalisé plus tôt lorsque l'utilsateur à terminer de taper.

#### 3.2 ---

Maintenant que votre logique d'input est séparé dans un hook personnalisé, créez un nouveau composant `SearchBar` en utilsant ce hook. 

Lorsque l'utilisateur fini de taper dans cette searchBar, afficher une `Alert` simplement.
Créez un bouton (une croix par exemple) pour rénitialiser l'input de la searchBar.

###### `Example:`

![](https://i.imgur.com/BPVVaXg.gif)


### Exercice 4: Other Hooks

Rappelez vous j'avais évoqué l'existence d'autre hooks pouvant être utils pour la suite de votre apprentissage en React/ React Native.

Voici simplement quelques vidéos utiles pour vous introduire correctement leur fonctionnement.
Aucun exercices ne sera demandé pour ceux-ci mais connaître leur existence et leur importance est nécessaire.

**useMemo & useCallback**: https://www.youtube.com/watch?v=wNX5iRhczHM
**useRef**: https://www.youtube.com/watch?v=A7mSiXePpW4
**useReducer**: https://www.youtube.com/watch?v=UlSulQxCh7I