Avec React 16.8.6 (c'était bien sur la version précédente 16.8.3), j'obtiens cette erreur lorsque je tente d'empêcher une boucle infinie sur une requête de récupération
./src/components/BusinessesList.js
Line 51: React Hook useEffect has a missing dependency: 'fetchBusinesses'.
Either include it or remove the dependency array react-hooks/exhaustive-deps
J'ai été incapable de trouver une solution qui arrête la boucle infinie. Je veux éviter d'utiliser useReducer()
. J'ai trouvé cette discussion https://github.com/facebook/react/issues/14920 où une solution possible est You can always // eslint-disable-next-line react-hooks/exhaustive-deps if you think you know what you're doing.
que je ne suis pas sûr de ce que je fais donc je n'ai pas encore essayé de l'implémenter.
J'ai cette configuration actuelle React hook useEffect fonctionne en continu pour toujours / boucle infinie et le seul commentaire est useCallback()
que je ne connais pas.
Comment j'utilise actuellement useEffect()
(que je ne veux exécuter qu'une seule fois au début, similaire à componentDidMount()
)
useEffect(() => {
fetchBusinesses();
}, []);
const fetchBusinesses = () => {
return fetch("theURL", {method: "GET"}
)
.then(res => normalizeResponseErrors(res))
.then(res => {
return res.json();
})
.then(rcvdBusinesses => {
// some stuff
})
.catch(err => {
// some error handling
});
};
useCallback()
. Donc par exemple:const fetchBusinesses= useCallback(() => { ... }, [...])
etuseEffect()
cela ressemblerait à ceci:useEffect(() => { fetchBusinesses(); }, [fetchBusinesses]);
// eslint-disable-next-line react-hooks/exhaustive-deps
pour expliquer au linter que votre code est correct est comme un hack. J'espère qu'ils trouveront une autre solution pour rendre le linter suffisamment intelligent pour détecter quand une dispute n'est pas obligatoireCe n'est pas une erreur JS / React mais un avertissement eslint (eslint-plugin-react-hooks).
Cela vous indique que le hook dépend de la fonction
fetchBusinesses
, vous devez donc le passer en tant que dépendance.Cela pourrait entraîner l'appel de la fonction à chaque rendu si la fonction est déclarée dans un composant comme:
car chaque fonction de temps est redéclarée avec une nouvelle référence
La bonne façon de faire cela est:
ou simplement définir la fonction dans
useEffect
En savoir plus: https://github.com/facebook/react/issues/14920
la source
Line 20: The 'fetchBusinesses' function makes the dependencies of useEffect Hook (at line 51) change on every render. Move it inside the useEffect callback. Alternatively, wrap the 'fetchBusinesses' definition into its own useCallback() Hook
Vous pouvez le définir directement comme
useEffect
rappel:Il ne se déclenchera qu'une seule fois, alors assurez-vous que toutes les dépendances de la fonction sont correctement définies (comme pour l'utilisation
componentDidMount/componentWillMount...
)Modifier 21/02/2020
Juste pour être complet:
1. Utilisez la fonction comme
useEffect
rappel (comme ci-dessus)2. Déclarez la fonction à l'intérieur
useEffect()
3. Mémorisez avec
useCallback()
Dans ce cas, si vous avez des dépendances dans votre fonction, vous devrez les inclure dans le
useCallback
tableau des dépendances et cela déclenchera àuseEffect
nouveau si les paramètres de la fonction changent. D'ailleurs, c'est beaucoup de passe-partout ... Il suffit donc de passer la fonction directement àuseEffect
as in1. useEffect(fetchBusinesses, [])
.4. Désactivez l'avertissement d'eslint
la source
La solution est également donnée par react, ils vous conseillent d'utiliser
useCallback
qui vous renverra une version mémoriser de votre fonction:useCallback
est simple à utiliser car il a la même signature caruseEffect
la différence est que useCallback renvoie une fonction. Cela ressemblerait à ceci:la source
Ces avertissements sont très utiles pour trouver les composants qui ne se mettent pas à jour de manière cohérente: https://reactjs.org/docs/hooks-faq.html#is-it-safe-to-omit-functions-from-the-list-of- dépendances .
Cependant, si vous souhaitez supprimer les avertissements tout au long de votre projet, vous pouvez l'ajouter à votre configuration eslint:
la source
Cet article est une bonne introduction à la récupération de données avec des hooks: https://www.robinwieruch.de/react-hooks-fetch-data/
Essentiellement, incluez la définition de la fonction fetch à l'intérieur
useEffect
:la source
Vous pouvez supprimer le 2ème tableau de type d'argument
[]
mais lefetchBusinesses()
sera également appelé à chaque mise à jour. Vous pouvez ajouter uneIF
instruction dans l'fetchBusinesses()
implémentation si vous le souhaitez.L'autre consiste à implémenter la
fetchBusinesses()
fonction en dehors de votre composant. N'oubliez pas de transmettre des arguments de dépendance à votrefetchBusinesses(dependency)
appel, le cas échéant.la source
En fait, les avertissements sont très utiles lorsque vous développez avec des hooks. mais dans certains cas, cela peut vous aiguiller. surtout lorsque vous n'avez pas besoin d'écouter le changement des dépendances.
Si vous ne voulez pas mettre
fetchBusinesses
à l'intérieur des dépendances du hook, vous pouvez simplement le passer comme argument au callback du hook et définir le mainfetchBusinesses
comme valeur par défaut comme ceciCe n'est pas la meilleure pratique, mais cela pourrait être utile dans certains cas.
De plus, comme Shubnam l'a écrit, vous pouvez ajouter le code ci-dessous pour indiquer à ESLint d'ignorer la vérification de votre hook.
la source
Vous pouvez retirer
fetchBusinesses
complètement votre composant:Cela ne fournira pas seulement une solution simple et résoudra l'avertissement exhaustif deps.
fetchBusiness
peut maintenant être testé mieux et faciliteComp
, car il réside dans la portée du module en dehors de l'arborescence React.Le déménagement à l'
fetchBusinesses
extérieur fonctionne bien ici, car nous ne pourrions lire que les accessoires initiaux et l'état du composant de toute façon en raison de la portée de fermeture périmée ([]
dép dansuseEffect
).Comment omettre les dépendances de fonction
useEffect
dépendre de cette valeur (fonction de calcul pure)useCallback
en dernier recoursConcernant les autres solutions:
Tirer à l'
fetchBusinesses
intérieuruseEffect()
n'aide pas vraiment, si vous accédez à un autre état. eslint se plaindrait toujours: Codesandbox .Je voudrais également éviter d'eslint exhaustif-deps ignorer les commentaires. Il est juste trop facile de les oublier lorsque vous refactorisez et remaniez vos dépendances.
la source
Cette solution est assez simple et vous n'avez pas besoin de remplacer les avertissements es-lint. Maintenez simplement un indicateur pour vérifier si le composant est monté ou non.
la source
vous essayez de cette façon
et
c'est du travail pour vous. Mais ma suggestion est que cette méthode fonctionne également pour vous. C'est mieux qu'avant. J'utilise de cette façon:
si vous obtenez des données sur la base d'un identifiant spécifique, ajoutez un callback useEffect
[id]
alors ne peut pas vous montrer d'avertissementReact Hook useEffect has a missing dependency: 'any thing'. Either include it or remove the dependency array
la source
désactivez simplement eslint pour la ligne suivante;
de cette façon, vous l'utilisez comme un composant l'a fait mount (appelé une fois)
actualisé
ou
fetchBusinesses sera appelé à chaque fois que certainsDeps changeront
la source
[fetchBusinesses]
supprimera automatiquement l'avertissement et cela a résolu le problème pour moi.useEffect
qui vérifie si l'état est vide.