Blog -

Gérer l'état plus facilement avec React Hooks
Dans mon travail quotidien chez FloQast, il m'arrivera souvent de rencontrer une situation particulière avec le développement React. Afin de basculer les effets CSS sur certains composants, je vais souvent :
- Convertir le composant fonctionnel en composant de classe et ajouter un état local
- Créer un composant d'ordre supérieur s'il existe une logique commune à plusieurs composants
- Faire passer les accessoires par plusieurs composants jusqu'à leurs consommateurs finaux
- Faire des mises à jour et écrire des tests
C'est beaucoup.
Je me suis souvent demandé s'il n'y avait pas une meilleure façon de le faire - et maintenant il y en a une ! Depuis que l'équipe React a publié la version 16.8, nous pouvons nous attaquer à ces problèmes d'une manière très élégante en utilisant React Hooks.
Qu'est-ce que React Hooks ?
Selon le site officiel de React, les Hooks sont une nouveauté de React 16.8. Ils vous permettent d'utiliser l'état et d'autres fonctionnalités de React sans écrire de classe.
Sur la base de cette définition, votre première réaction pourrait être : "Ne vais-je pas simplement réécrire tous les composants de ma classe ?!" Les React Hooks sont bien plus qu'une refactorisation des mêmes API React.
Ajouter un état local à un composant fonctionnel
Examinons un composant de type bouton lorsqu'un utilisateur clique dessus pour modifier sa couleur d'arrière-plan :
import React, { useState } from ‘react’; const MyButton = () => { const [background, setBackground] = useState('blue'); const btnStyle = { background: background }; const changeBackground = () => { setBackground({ background: 'green' }); }; return <Button onclick={changeBackground} style={btnStyle}> My Button </Button>; }
Le composant ci-dessus possède une simple variable d'état background
pour enregistrer la couleur d'arrière-plan actuelle du bouton.
Existe-t-il un moyen de faire cela avec un composant fonctionnel ? Oui, avec l'aide de React Hooks useState
api. Voyons comment nous l'implémentons dans les Hooks :
import React, { useState } from ‘react’; const MyButton = () => { const [background, setBackground] = useState('blue'); const btnStyle = { background: background }; const changeBackground = () => { setBackground({ background: 'green' }); }; return <Button onclick={changeBackground} style={btnStyle}> My Button </Button>; }
Comme vous pouvez le constater, l'API React Hooks permet de créer un état local dans les composants fonctionnels, de réduire le code passe-partout lié aux classes et, par conséquent, de rendre le composant fonctionnel plus puissant.
Extraire la logique de l'état commun
Le choix d'utiliser des crochets dans les composants fonctionnels sans état vous permet également de vous débarrasser de la paperasse. Pensez au nombre de fois où vous avez écrit l'initialisation du constructeur de la classe et les fonctions de liaison pour vos méthodes. Voyons la différence avec les crochets :
import React from 'react'; class GetTime extends React.Component { constructor(props) { super(props); this.state = { time: null }; } checkTime() { this.setState({ time: new Date() }); } componentDidMount() { this.interval = setInterval(this.checkTime(), 1000); } componentWillUnMount() { clearInterval(this.interval); } render() { return <div>Current Time is: {this.state.time}</div> } }
Voyons maintenant ce qu'il en est après avoir utilisé Hooks
:
import React, { useState, useEffect } from ‘react’; const useTime = () => { const [time, setTime] = useState(null); useEffect(() => { const interval = setInterval(() => { setTime(new Date()); }, 1000); return () => clearInterval(interval); }, [time]); return time; } const GetTime = () => { const time = useTime(); return <div>Current Time is: {time}</div>; }
La comparaison montre qu'il existe une useTime
qui englobe la fonction obtenir l'heure actuelle et fixe l'heure à une variable d'état locale. Maintenant, tous peut l'utiliser pour afficher l'heure actuelle.
L'avantage de Hooks
Il s'agit ici de simplifier le code en extrayant la logique de l'état commun.
Fini l'enfer de l'emballage
Examinons un autre composant :
import React from 'react'; import ReactDOM from 'react-dom'; const withCounter = Component => { return class ComponentWithCounter extends React.Component { state = { count: 0, }; handleDecrement = () => { this.setState({ count: this.state.count - 1 }); }; handleIncrement = () => { this.setState({ count: this.state.count + 1 }); }; render() { const { count } = this.state; return ( <Component {...this.props} count={count} onIncrease={this.handleIncrement} onDecrease={this.handleDecrement} /> ); } }; }; const App = ({ count, onIncrease, onDecrease }) => { return ( <div> <div>Current count: {count}</div> <div> <button onClick={onDecrease}>-</button> <button onClick={onIncrease}>+</button> </div> </div> ); }; const AppWithCounter = withCounter(App); ReactDOM.render(<AppWithCounter />, document.getElementById('root'));
Ça vous dit quelque chose ? Oui, j'ai vu cela souvent aussi.
Et si nous transformions le composant ci-dessus en quelque chose comme ci-dessous :
import React, { useState } from 'react'; import ReactDOM from 'react-dom'; const useCounter = () => { const [count, setCount] = useState(0); const onIncrease = () => setCount(count + 1); const onDecrease = () => setCount(count - 1); return [ count, onIncrease, onDecrease ]; }; const App = () => { const [ count, onIncrease, onDecrease ] = useCounter(); return ( <div> <div>Current count: {count}</div> <div> <button onClick={onDecrease}>-</button> <button onClick={onIncrease}>+</button> </div> </div> ); }; ReactDOM.render(<App />, document.getElementById('root'));
Pas de wrapper ou de classe avec une implémentation de composant fonctionnel propre et agréable.
Démarrer avec React Hooks
Hooks
nous sont bénéfiques à plusieurs égards. Ils :
- Permettre l'état local et le cycle de vie des composants fonctionnels
- Permet d'extraire la logique partagée dans des crochets personnalisés
- Simplifier considérablement le code et vous aider à sortir de l'enfer des wrappers
Commencer n'est pas douloureux !
Voir ? Plaidoyer pour Hooks
ne signifie pas que vous devez remanier toutes les classes de votre base de données. Utilisez-les là où cela a du sens et vous vous retrouverez vite... accroché.
Si vous n'êtes pas suffisamment convaincu, la documentation officielle de hooks contient quelques arguments décents à prendre en compte, et j'espère que mon expérience vous sera utile.
Retour au blog