Wir haben ein Problem, Asynchronität ist schwierig.
Stellen Sie sich vor, Sie haben eine einfache GET-API, eine Suche, die als Parameter einen Suchtext empfängt. Sie rufen es mit Ihrem bevorzugten HTTP-Anfragetool auf und erhalten die Zusage, dass es in die Liste dessen aufgelöst wird, wonach Sie suchen.
Wie kann ich es in einer React-Komponente aufrufen?
Zuerst ist es wichtig, eines zu beachten: Das, was ich beschrieben habe, kann wie folgt modelliert werden:
result = await searchAPI(searchText);
Lassen Sie uns hier konzeptionell beginnen. Dies ist eine Ableitung. Für jede Version von searchText können Sie ein anderes Ergebnis erhalten. Aber hier gibt es einige Probleme:
Wie kann ich es als Ableitung in React aufrufen?
Die Verwendung von Bibliotheken von Drittanbietern wie TanStack Query und SWR löst unser Problem. Sie geben uns Hooks, die wir in einer React-Komponente verwenden können, um unsere Zustände und Requisiten zu empfangen und bei Änderungen eine Neuberechnung (Neuabruf) an die API durchzuführen. Schauen Sie sich dieses Beispiel an:
const { data: searchResult, loading } = useQuery({queryKey: [search, searchText],queryFn: getSearch,});
Ok, wir haben die asynchrone Ableitung gelöst, oder?
Nicht wirklich.
Übrigens empfehle ich immer, nur eine dieser Bibliotheken zu verwenden, sie sind großartig und sparen bei komplexeren Fällen (wie erneutem Abrufen, erneutem Versuch, Cache-Steuerung usw.) eine Menge Zeit, aber wir können nicht mit einer dritten rechnen -Partei zur Lösung eines konzeptionellen Problems von React.
Um noch einmal auf die Reaktivität zurückzukommen: Wir müssen eine Möglichkeit haben, mit asynchronen Fällen in einem Ableitungsmodell umzugehen. React sollte uns für diesen Fall ein Grundelement geben. Nun ja, bis Version 18 hatten wir es nicht, aber in 19 ist es anders.
React 19 führt ein neues Grundelement namens use ein. Ja, die Benennung ist etwas verwirrend, aber ihre Rolle im Reaktivitätsmodell von React ist ziemlich wichtig. Damit können wir Versprechen während des Renderns einer Komponente lösen. Die fehlende Ableitung.
Davor bestand die einzige Möglichkeit, einen Abruf während des Renderns einer Komponente aufzurufen, darin, useEffect zu verwenden, das Versprechen aufzurufen und in der then-Klausel einen Status mit dem Wert festzulegen, der als Antwort kommt. Das hat irgendwie funktioniert, aber wir hatten alle Probleme, einen Effekt dafür zu verwenden.
Das Verwendungsprimitiv ermöglicht es uns, das Versprechen während des Renderns der Komponente aufzulösen, sodass wir den Zustand und die Requisiten verwenden können, um das Versprechen zu erstellen, diese Versprechen dann aufzulösen und sie für unsere Funktionen und JSX zu verwenden.
const useCountTotal = (count: number) => { const countTotalPromise = useMemo(() => genericPromise(count), [count]); const result = use(countTotalPromise); return result; } function AsyncDerivation({count}: { count: number}) { const result = useCountTotal(count); return ( <div>Total count is: {result}</div> ) }
Im Moment, in dem ich dies schreibe, haben wir noch nicht die endgültige Version von React 19. Es gibt einige Einschränkungen und wahrscheinlich wird sich das Primitiv in Zukunft weiterentwickeln, um an mehr Orten zu funktionieren.
Eine Besonderheit der primitiven Verwendung ist, dass sie mit Suspense verwendet werden muss, und dafür gibt es einen sehr guten Grund.
Die konzeptionelle Idee von „await“ ist nett, weist jedoch bei der Verbindung mit React-Komponenten einen Fehler auf. Sie können „await“ nicht einfach während des Renderns verwenden. React ruft eine Komponente auf, um die JSX-Antwort abzurufen und sie in ihrem Flow zum Rendern einer Benutzeroberfläche zu verwenden.
Wenn wir einfach alles in einem Wartezustand stoppen könnten, könnte React nicht auf die untergeordneten Elemente dieser Komponente zugreifen und seine Arbeit bis zum Ende des Baums fortsetzen. Wir würden den Renderfluss stoppen und dafür sorgen, dass die Benutzeroberfläche nicht aktualisiert wird und einfriert.
Wie kann man das lösen?
Wir können uns die beiden Beispiele ansehen, die ich in diesem Artikel verwendet habe. Der erste Ansatz verfolgt den Ansatz, Flags wie das Laden zurückzugeben und nicht den Renderfluss zu blockieren. Wenn das Versprechen aufgelöst ist, wird ein erneutes Rendern ausgelöst, die Flags werden aktualisiert, der Ladevorgang wird auf „Falsch“ gesetzt und die Daten empfangen die Antwortdaten.
Der Nutzungsansatz ist anders. Es verhält sich wirklich wie das Warte-Primitiv, sodass der Renderfluss der Komponente dort bis zur Auflösung angehalten wird.
Warte, warte, warte, du hast gesagt, es sei ein Problem, oder?
Und hier kommt die Spannung um die Erlösung. Wenn Sie das Verwendungsprimitiv verwenden, wird es in eine Suspense-Komponente eingeschlossen, der Renderfluss hört auf, auf die Verwendungsauflösung zu warten, und der Benutzer erhält das auf der Benutzeroberfläche gerenderte Fallback (normalerweise ein Ladespinner oder ein Ladeskelett, etwas, das uns anzeigt). laden dort ein paar Sachen).
Wenn das Nutzungsversprechen gelöst ist, fahren wir mit dem Rendern fort und aktualisieren die Benutzeroberfläche entsprechend. UseEffect.
muss nicht verwendet werdenDas Verwendungsprimitiv wird für Bibliotheksautoren sehr nützlich sein, die Suspense verwenden und mit asynchronem Verhalten arbeiten möchten. Für den App-Entwickler wird ein weiterer Fall im grundlegenden Reaktivitätsmodell behoben, der sich hervorragend für einfache Anwendungsfälle eignet. Da es Versprechen umschließt, ist es nicht nur auf HTTP-Anfragen beschränkt, sondern auf alle asynchronen Fälle und die externe API-Nutzung, wodurch dem Ökosystem weitere Ressourcen hinzugefügt werden können.
Das obige ist der detaillierte Inhalt vonAsynchrone Ableitungen in React. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!