Mit React 16.8.6 (es war in der vorherigen Version 16.8.3 gut) erhalte ich diesen Fehler, wenn ich versuche, eine Endlosschleife bei einer Abrufanforderung zu verhindern
./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
Ich konnte keine Lösung finden, die die Endlosschleife stoppt. Ich möchte mich von der Verwendung fernhalten useReducer()
. Ich habe diese Diskussion unter https://github.com/facebook/react/issues/14920 gefunden, bei der eine mögliche Lösung darin besteht, dass You can always // eslint-disable-next-line react-hooks/exhaustive-deps if you think you know what you're doing.
ich nicht sicher bin, was ich tue. Daher habe ich noch nicht versucht, sie zu implementieren.
Ich habe dieses aktuelle Setup. React hook useEffect läuft ununterbrochen für immer / Endlosschleife und der einzige Kommentar ist, mit useCallback()
dem ich nicht vertraut bin.
Wie ich aktuell benutze useEffect()
(was ich am Anfang nur einmal ausführen möchte, ähnlich wie 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()
. Also zum Beispiel:const fetchBusinesses= useCallback(() => { ... }, [...])
und dasuseEffect()
würde so aussehen:useEffect(() => { fetchBusinesses(); }, [fetchBusinesses]);
// eslint-disable-next-line react-hooks/exhaustive-deps
ist wie ein Hack, dem Linter zu erklären, dass Ihr Code korrekt ist. IchEs ist kein JS / React-Fehler, sondern eine Eslint-Warnung (Eslint-Plugin-React-Hooks).
Es sagt Ihnen, dass der Hook von der Funktion abhängt
fetchBusinesses
, also sollten Sie ihn als Abhängigkeit übergeben.Es kann dazu führen, dass bei jedem Rendern eine Funktion aufgerufen wird, wenn die Funktion in einer Komponente wie folgt deklariert ist:
weil jede Zeitfunktion mit neuer Referenz neu deklariert wird
Die richtige Vorgehensweise ist:
oder einfach nur die Funktion in definieren
useEffect
Mehr: https://github.com/facebook/react/issues/14920
quelle
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
Sie können es direkt als
useEffect
Rückruf festlegen :Es wird nur einmal ausgelöst. Stellen Sie daher sicher, dass alle Abhängigkeiten der Funktion korrekt eingestellt sind (wie bei Verwendung von
componentDidMount/componentWillMount...
).Bearbeiten 21.02.2020
Nur der Vollständigkeit halber:
1. Verwenden Sie die Funktion als
useEffect
Rückruf (wie oben).2. Deklarieren Sie die Funktion im Inneren
useEffect()
3. Merken Sie sich mit
useCallback()
In diesem Fall müssen Sie Abhängigkeiten in Ihre Funktion aufnehmen, wenn Sie Abhängigkeiten in Ihrer Funktion haben.
useCallback
Dies wird erneut ausgelöstuseEffect
, wenn sich die Parameter der Funktion ändern. Außerdem ist es eine Menge Boilerplate ... Also einfach die Funktion direkt anuseEffect
wie in übergeben1. useEffect(fetchBusinesses, [])
.4. Deaktivieren Sie die Warnung von eslint
quelle
Die Lösung wird auch durch Reagieren gegeben. Sie empfehlen Ihnen,
useCallback
eine Memoize-Version Ihrer Funktion zurückzugeben:useCallback
ist einfach zu verwenden, da es dieselbe Signatur hat, dauseEffect
der Unterschied darin besteht, dass useCallback eine Funktion zurückgibt. Es würde so aussehen:quelle
Diese Warnungen sind sehr hilfreich, um Komponenten zu finden, die nicht konsistent aktualisiert werden: https://reactjs.org/docs/hooks-faq.html#is-it-safe-to-omit-functions-from-the-list-of- Abhängigkeiten .
Wenn Sie jedoch die Warnungen in Ihrem Projekt entfernen möchten, können Sie dies zu Ihrer eslint-Konfiguration hinzufügen:
quelle
Dieser Artikel ist eine gute Einführung in das Abrufen von Daten mit Hooks: https://www.robinwieruch.de/react-hooks-fetch-data/
Fügen Sie im Wesentlichen die Definition der Abruffunktion hinzu
useEffect
:quelle
Sie können das Array vom 2. Argumenttyp entfernen
[]
, dasfetchBusinesses()
wird jedoch auch bei jedem Update aufgerufen. Sie könnenIF
derfetchBusinesses()
Implementierung eine Anweisung hinzufügen , wenn Sie möchten.Die andere besteht darin, die
fetchBusinesses()
Funktion außerhalb Ihrer Komponente zu implementieren . Vergessen Sie nur nichtfetchBusinesses(dependency)
, gegebenenfalls Abhängigkeitsargumente an Ihren Aufruf zu übergeben.quelle
Eigentlich sind die Warnungen sehr nützlich, wenn Sie mit Hooks entwickeln. aber in einigen Fällen kann es Sie nadeln. vor allem, wenn Sie nicht auf Abhängigkeitsänderungen warten müssen.
Wenn Sie
fetchBusinesses
die Abhängigkeiten des Hooks nicht einfügen möchten , können Sie sie einfach als Argument an den Rückruf des Hooks übergeben und den HauptwertfetchBusinesses
wie folgt als Standardwert festlegenDies ist keine bewährte Methode , kann jedoch in einigen Fällen hilfreich sein.
Wie Shubnam schrieb, können Sie den folgenden Code hinzufügen, um ESLint anzuweisen, die Überprüfung auf Ihren Hook zu ignorieren.
quelle
Sie können
fetchBusinesses
vollständig aus Ihrer Komponente herausziehen :Dies bietet nicht nur eine einfache Lösung und löst die erschöpfende Warnung.
fetchBusiness
Jetzt kann es besser getestet werden und erleichtert sichComp
, da es sich im Modulbereich außerhalb des Reaktionsbaums befindet.Der Umzug nach
fetchBusinesses
draußen funktioniert hier gut, da wir aufgrund des veralteten Verschlussbereichs ( dep in ) ohnehin nur die ersten Requisiten und den Status der Komponente lesen können .[]
useEffect
So lassen Sie Funktionsabhängigkeiten aus
useEffect
von diesem Wert abhängen lassen (reine Berechnungsfunktion)useCallback
als letzten Ausweg einIn Bezug auf andere Lösungen:
Das Ziehen nach
fetchBusinesses
innenuseEffect()
hilft nicht wirklich, wenn Sie auf einen anderen Status zugreifen. eslint würde sich immer noch beschweren: Codesandbox .Ich würde mich auch davor zurückhalten, erschöpfende Kommentare zu ignorieren. Es ist einfach zu leicht, sie zu vergessen, wenn Sie Ihre Abhängigkeiten umgestalten und überarbeiten.
quelle
Diese Lösung ist ziemlich einfach und Sie müssen es-lint-Warnungen nicht überschreiben. Behalten Sie einfach ein Flag bei, um zu überprüfen, ob die Komponente bereitgestellt ist oder nicht.
quelle
du versuchst es so
und
Es ist Arbeit für dich. Aber mein Vorschlag ist, auf diese Weise zu versuchen, auch für Sie zu arbeiten. Es ist besser als vorher. Ich benutze diesen Weg:
Wenn Sie Daten auf der Basis einer bestimmten ID erhalten, fügen Sie im Rückruf useEffect hinzu,
[id]
und Sie können keine Warnung anzeigenReact Hook useEffect has a missing dependency: 'any thing'. Either include it or remove the dependency array
quelle
Deaktivieren Sie einfach eslint für die nächste Zeile.
Auf diese Weise verwenden Sie es genau wie eine Komponente (einmal aufgerufen).
Aktualisiert
oder
fetchBusinesses wird jedes Mal aufgerufen, wenn sich someDeps ändern
quelle
[fetchBusinesses]
Die Warnung wird automatisch entfernt, und das Problem wurde für mich behoben.useEffect
prüft, ob der Status leer ist.