J'ai parcouru les crochets introduits dans react v16.7.0.
https://reactjs.org/docs/hooks-intro.html
Donc, ma compréhension des crochets est que nous pouvons jouer avec l'état dans le composant fonctionnel sans écrire les composants de classe en réaction. C'est une fonctionnalité vraiment incroyable.
Mais je n'ai pas une idée claire de l'utilisation des crochets dans les composants fonctionnels.
import { useState } from 'react';
function Example() {
const [count, setCount] = useState(0);
return (
<div>
<p>You clicked {count} times</p>
<button onClick={() => setCount(count + 1)}>
Click me
</button>
</div>
);
}
comment puis-je utiliser des méthodes de cycle de vie dans le composant fonctionnel ci-dessus si j'utilise des crochets?
Voici des exemples des cycles de vie les plus courants:
componentDidMount
Passez un tableau vide comme deuxième argument à useEffect()
pour exécuter uniquement le rappel sur le montage uniquement.
function Example() {
const [count, setCount] = useState(0);
useEffect(() => {
document.title = `You clicked ${count} times`;
}, []); // Pass an empty array to run only callback on mount only.
return (
<div>
<p>You clicked {count} times</p>
<button onClick={() => setCount(count + 1)}>
Click me
</button>
</div>
);
}
componentDidUpdate
(lâche)En passant juste le seul argument dans useEffect
, il s'exécutera après chaque rendu. C'est un équivalent lâche car il y a une légère différence ici étant que componentDidUpdate
ne s'exécutera pas après le premier rendu mais cette version de hooks s'exécute après chaque rendu.
function Example() {
const [count, setCount] = useState(0);
useEffect(() => {
document.title = `You clicked ${count} times`;
}); // No second argument, so run after every render.
return (
<div>
<p>You clicked {count} times</p>
<button onClick={() => setCount(count + 1)}>
Click me
</button>
</div>
);
}
componentDidUpdate
(strict)La différence de cet exemple avec l'exemple ci-dessus est que le rappel ici ne s'exécuterait pas sur le rendu initial, émulant strictement la sémantique de componentDidUpdate
. Ce la réponse est de Tholle , tout le mérite lui revient.
function Example() {
const [count, setCount] = useState(0);
const firstUpdate = useRef(true);
useLayoutEffect(() => {
if (firstUpdate.current) {
firstUpdate.current = false;
return;
}
console.log('componentDidUpdate');
});
return (
<div>
<p>componentDidUpdate: {count} times</p>
<button
onClick={() => {
setCount(count + 1);
}}
>
Click Me
</button>
</div>
);
}
componentWillUnmount
Renvoie un rappel dans l'argument de rappel de useEffect
et il sera appelé avant le démontage.
function Example() {
const [count, setCount] = useState(0);
useEffect(() => {
// Return a callback in useEffect and it will be called before unmounting.
return () => {
console.log('componentWillUnmount!');
};
});
return (
<div>
<p>You clicked {count} times</p>
<button onClick={() => setCount(count + 1)}>
Click me
</button>
</div>
);
}
shouldComponentUpdate
Vous pouvez déjà y parvenir au niveau du composant à l'aide de React.PureComponent
ou React.memo
. Pour empêcher le rendu des composants enfants, cet exemple est tiré de React docs :
function Parent({ a, b }) {
// Only re-rendered if `a` changes:
const child1 = useMemo(() => <Child1 a={a} />, [a]);
// Only re-rendered if `b` changes:
const child2 = useMemo(() => <Child2 b={b} />, [b]);
return (
<>
{child1}
{child2}
</>
)
}
getDerivedStateFromProps
Encore une fois, tiré de la React docs
function ScrollView({row}) {
let [isScrollingDown, setIsScrollingDown] = useState(false);
let [prevRow, setPrevRow] = useState(null);
if (row !== prevRow) {
// Row changed since last render. Update isScrollingDown.
setIsScrollingDown(prevRow !== null && row > prevRow);
setPrevRow(row);
}
return `Scrolling down: ${isScrollingDown}`;
}
getSnapshotBeforeUpdate
Pas encore d'équivalent pour les crochets.
componentDidCatch
Pas encore d'équivalent pour les crochets.
L'équipe React a fourni un hook useEffect
à cet effet. Prenons le composant dans votre exemple et ajoutons le téléchargement du serveur pour le décompte, que nous mettrions autrement par exemple componentDidUpdate
:
import { useState, useEffect } from 'react';
function Example() {
const [count, setCount] = useState(0);
useEffect(() => {
fetch(
'server/url',
{
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
body: JSON.stringify({count}),
}
);
});
return (
<div>
<p>You clicked {count} times</p>
<button onClick={() => setCount(count + 1)}>
Click me
</button>
</div>
);
}
Cela ne semble pas être une énorme victoire dans cet exemple, car ce n'est pas le cas. Mais le problème avec les méthodes de cycle de vie est que vous n'en obtenez qu'une seule dans votre composant. Que faire si vous souhaitez télécharger sur le serveur, déclencher un événement et mettre un message dans une file d'attente, et aucune de ces choses n'est liée? Dommage, ils sont tous entassés dans componentDidUpdate
. Ou vous avez n
couches de HOC enveloppés pour vos n
choses que vous voulez faire. Mais avec les hooks, vous pouvez diviser tout cela en appels découplés vers useEffect
sans couches de HOC inutiles.
Eh bien, vous n'avez pas vraiment de méthodes de cycle de vie. =) Mais vous pouvez utiliser le crochet d'effet comme indiqué ici https://reactjs.org/docs/hooks-effect.html
Le hook d'effet pourra répliquer le comportement de componentDidMount, componentDidUpdate et componentWillUnmount
Vous n'avez donc vraiment pas besoin de méthodes de cycle de vie dans le composant. Le crochet d'effet prend sa place à la place. =)
Lisez le lien ci-dessus et vous obtiendrez quelques exemples sur leur fonctionnement.