Comment utiliser le hook useCallback React

Découvrez à quoi sert le hook useCallback React et comment l'utiliser!

Découvrez monPrésentation des crochets Reactd'abord, si vous êtes nouveau pour eux.

Un hook React que j'utilise parfois estuseCallback.

import React, { useCallback } from 'react'

Ce hook est utile lorsque vous avez un composant avec un enfant fréquemment re-rendu et que vous lui passez un rappel:

import React, { useState, useCallback } from 'react'

const Counter = () => { const [count, setCount] = useState(0) const [otherCounter, setOtherCounter] = useState(0)

const increment = () => { setCount(count + 1) } const decrement = () => { setCount(count - 1) } const incrementOtherCounter = () => { setOtherCounter(otherCounter + 1) }

return ( <> Count: {count} <button onClick={increment}>+</button> <button onClick={decrement}>-</button> <button onClick={incrementOtherCounter}>incrementOtherCounter</button> </> ) }

ReactDOM.render(<Counter />, document.getElementById(‘app’))

Le problème ici est que chaque fois que le compteur est mis à jour, les 3 fonctions sont recréées à nouveau.

Vous pouvez visualiser cela en instanciant unDéfinir la structure des données, et en y ajoutant chaque fonction. Pourquoi définir? car il ne stocke que des éléments uniques, ce qui dans notre cas signifie différentes fonctions (instanciées de manière unique).

import React, { useState, useCallback } from 'react'

const functionsCounter = new Set()

const Counter = () => { const [count, setCount] = useState(0) const [otherCounter, setOtherCounter] = useState(0)

const increment = () => { setCount(count + 1) } const decrement = () => { setCount(count - 1) } const incrementOtherCounter = () => { setOtherCounter(otherCounter + 1) }

functionsCounter.add(increment) functionsCounter.add(decrement) functionsCounter.add(incrementOtherCounter)

alert(functionsCounter)

return ( <> Count: {count} <button onClick={increment}>+</button> <button onClick={decrement}>-</button> <button onClick={incrementOtherCounter}>incrementOtherCounter</button> </> ) }

ReactDOM.render(<Counter />, document.getElementById(‘app’))

Si vous essayez ce code, vous verrez l'alerte incrémentée de 3 à la fois.

Ce qui devrait plutôt arriver, c'est que si vous incrémentez un compteur, toutes les fonctions liées à ce compteur doivent être ré-instanciées.

Si une autre valeur d'état est inchangée, elle ne doit pas être touchée.

Maintenant, dans la plupart des cas, ce n'est pas un énorme problème à moins que vous ne transmettiez de nombreuses fonctions différentes, toutes modifiant des bits de données non liés, qui s'avèrent être un coût élevé pour les performances de votre application.

Si c'est un problème, vous pouvez utiliseruseCallback.

C'est comme ça qu'on fait. Au lieu de:

const increment = (() => {
  setCount(count + 1)
})
const decrement = (() => {
  setCount(count - 1)
})
const incrementOtherCounter = (() => {
  setOtherCounter(otherCounter + 1)
})

Vous encapsulez tous ces appels dans:

const increment = useCallback(() => {
  setCount(count + 1)
}, [count])
const decrement = useCallback(() => {
  setCount(count - 1)
}, [count])
const incrementOtherCounter = useCallback(() => {
  setOtherCounter(otherCounter + 1)
}, [otherCounter])

Assurez-vous d'ajouter ce tableau en tant que deuxième paramètre àuseCallback()avec l'état nécessaire.

Désormais, si vous essayez de cliquer sur l'un des compteurs, seules les fonctions liées à l'état des modifications vont être ré-instanciées.

Vous pouvez essayer cet exemple sur Codepen:

Voir le styloRéagir l'utilisationCrochet de rappelpar Flavio Copes (@flaviocopes) surCodePen.

Tech Wiki Online!