Heim >Web-Frontend >js-Tutorial >React Update Notes Companion

React Update Notes Companion

Linda Hamilton
Linda HamiltonOriginal
2025-01-12 16:39:44892Durchsuche

React Update Notes Companion

Aktualisierungsnotizen für neue Hauptversionen von React sind immer unglaublich informationsreich, und das Framework selbst ist so umfangreich, dass ich mir immer Notizen mache und die Dokumentation mit Referenzdokumenten vergleiche, um zu versuchen, nicht nur Finden Sie heraus, was sich geändert hat und wie Sie es verwenden, aber auch, wie die verschiedenen Hauptkonzepte, über die in den Update-Notizen gesprochen wird, tatsächlich unter der Haube funktionierten. Obwohl React sehr gut dokumentiert ist, reichen die Update-Notizen nicht immer aus, um die Konzepte zu verstehen – in den React 19-Update-Notizen fand ich beispielsweise das Beispiel von useOptimistic verwirrend und tatsächlich ein wenig ungenau, wie der Hook tatsächlich funktioniert.

Ich habe beschlossen, die Notizen, die ich beim Durchgehen der React 19-Änderungen gemacht habe, als Begleiter für alle aufzuschreiben, die sich davor gefürchtet haben, die Notizen durchzugehen und herauszufinden, was sie alle bedeuten – also fangen wir an.

Aktionen und Formularverarbeitung/useActionState

Die erste große Verbesserung waren enorme Verbesserungen bei der Formularverarbeitung. React ist nach und nach dazu übergegangen, Boilerplates zu entfernen und sich besser in native HTML-Formulare zu integrieren, und sein neuer useActionState ist Teil dieses Vorstoßes. Es soll zur Verbesserung der Fehlerbehandlung beitragen (da es jetzt integriert ist), es verfolgt automatisch Ladezustände, sodass Sie nicht ständig manuell in ausstehende Zustände programmieren müssen, und verbessert die Unterstützung für progressive Verbesserungen.

Nun, ich fand das für useActionState bereitgestellte Codebeispiel ziemlich verwirrend, und tatsächlich ist dieses Codebeispiel der einzige Grund, warum ich mit dem Schreiben dieses Artikels begonnen habe – es gibt tatsächlich zwei Teile von useActionState, die sie im kombiniert haben Beispiel, um Platz zu sparen, hat aber letztlich die Übersichtlichkeit stark eingeschränkt. useActionState gibt ein Tupel zurück, das verfolgt, wann die asynchrone Aktion in der Formularübermittlung abgeschlossen ist, während eine geänderte Version der von Ihnen übergebenen Aktion direkt an das Formular übergeben wird. useActionState selbst benötigt zwei Eingaben – eine asynchrone formAction (die beim Aufruf sowohl den vorherigen Status als auch die Formulardaten als Argumente empfängt) und den Anfangsstatus – der null, null oder eine Variable sein kann.

Wenn Ihr Formular noch nicht übermittelt wurde, ist der vorherige Status der Anfangsstatus. Wenn das Formular zuvor übermittelt wurde, ist es das, was übermittelt wurde – in einer Serverfunktion können Sie die Serverantwort tatsächlich anzeigen, bevor überhaupt eine Flüssigkeitszufuhr erfolgt. useActionState kann schließlich eine Zeichenfolge mit einer eindeutigen Seiten-URL akzeptieren, die das Formular ändern soll. Mit anderen Worten: Es kann auch einen optionalen Permalink-Parameter akzeptieren, der besonders für die progressive Erweiterung nützlich ist – er teilt dem Browser mit, wohin er navigieren soll, wenn ein Benutzer das Formular abschickt, bevor JavaScript geladen wurde.

Schließlich ist das Tupel, das useActionState zurückgibt, ein Array, das aus dem aktuellen Status (während Ihres ersten Renderns ist es Ihr initialState-Wert), der durch die Reaktion geänderten formAction, die Sie als Aktion oder eine Schaltfläche als Requisite an ein Formular übergeben können, besteht. und ein isPending-Flag/eine zustandsbehaftete Variable. Ich bin gespannt, welche weiteren neuen Entwicklungen das React-Team hervorbringen wird, da diese besonders nützlich erscheint.

React-DOM-Updates

Aktionen

Dieser React-Dom-Zusatz wird jedem bekannt sein, der NextJS und Formularaktionen verwendet hat, und es scheint, dass das Reac-Team entschieden hat, dass Formularaktionen für die Hauptsendezeit bereit sind. Für alle, die sie noch nicht in NextJS oder einem anderen Framework zusätzlich zu React verwendet haben, sind sie im Grunde eine Möglichkeit, die Leistung von React durch die Verwendung nativer Formularübermittlung zu verbessern. Anstelle von onClick können Sie native Formularübermittlungen über die Action-Requisite übergeben – die Übermittlung jeder an action oder formAction übergebenen Funktion erfolgt automatisch. React setzt außerdem alle unkontrollierten Formularfelder automatisch zurück. Sie haben auch manuelle Optionen zum Zurücksetzen über die API. Das React-Team hat außerdem die Fehlerbehandlung mit Fehlergrenzen integriert. Ich werde nicht zu viel darüber reden, da ich davon ausgehe, dass sich die meisten Leute an NextJS erinnern, aber ich kann ein Follow-up schreiben, wenn jemand Fragen hat.

useFormStatus-Hook

Dies ist eine großartige Ergänzung, die Ihnen hilft, zu sehen, was in Ihrem Formular vor sich geht, ohne Prop-Drilling oder die Verwendung von Kontext – wenn Sie sich fragen, warum nicht Prop-Drill, geht es darum, den Code wartbar und leicht zu ändern. Was den Kontext betrifft, führt eine übermäßige Nutzung des Kontexts zu Leistungsproblemen, da jede Komponente, die einen bestimmten Kontext abonniert hat, immer dann neu gerendert wird, wenn sich etwas im Kontext ändert. Dadurch wird der Code übersichtlicher, die Fehlerwahrscheinlichkeit verringert und verhindert, dass die Leistung Ihrer App beeinträchtigt wird.

Der Hook gibt ein Objekt mit vier Eigenschaften zurück: pending – ein boolescher Wert, der angibt, ob eine Übermittlung aussteht, data – ein formData-Objekt mit den vom übergeordneten Formular übermittelten Daten (dies ist null, wenn keine aktive Übermittlung oder kein übergeordnetes Formular vorhanden ist). ), Methode (Get oder Post) und Aktion – das ist die Aktion, die durch die Aktionsstütze übergeben wird.

Verwenden Sie den Optimistic-Hook

Die neue, einfachere Möglichkeit, optimistische Updates zu verwalten. Wenn Sie mit optimistischen Updates nicht vertraut sind, bedeutet das, dass Sie die Anzeige auf der Clientseite aktualisieren müssen, bevor die Updates auf der Serverseite erfolgen. Wenn Ihnen schon einmal etwas gefallen hat, Sie die Animation gesehen haben und sie auf Ihrem Bildschirm als „Gefällt mir“ registriert haben und dann eine Toast-Fehlermeldung mit der Meldung „Gefällt mir nicht“ erhalten haben, liegt das an der optimistischen Darstellung.

Der useOptimistic-Hook akzeptiert eine zustandsbehaftete Variable, die optimistisch gerendert werden soll, und eine Update-Funktion, die eine reine Funktion sein muss – mit anderen Worten, eine deterministische Funktion ohne Nebenwirkungen. Grundsätzlich ruft die Update-Funktion die Quelle des Update-Status ab – normalerweise also so etwas wie formData.get(‘name’). useOptimistic gibt dann zwei Werte zurück: den optimistischen Zustand und eine addOptimistic-Funktion.

Ich fand die Dokumentation dazu etwas schwach, insbesondere im Hinblick auf den Nutzungsablauf – im Grunde ruft man useOptimistic auf und übergibt ihm den Anfangszustand, für den man optimistische Updates anzeigen möchte, sowie eine Update-Funktion. Sie erhalten zwei Funktionen – den neuen optimistisch erweiterten Zustandswert (optimisticState) und eine Funktion zum optimistischen Ändern des Zustands. Wenn Sie einen neuen Wert vom Benutzer übermittelt haben, rufen Sie die zweite Funktion auf, die in den Dokumenten als „addOptimistic“ bezeichnet wird, und übergeben ihr den vom Benutzer übermittelten Wert. In Ihrer Komponente übergeben Sie ihr dann den optimistisch erweiterten Zustandswert, wann immer Sie die Zustandsvariable optimistisch rendern möchten.

Im Großen und Ganzen gefällt mir diese standardisiertere Methode zur Durchführung optimistischer Aktualisierungen sehr gut – ich hatte zuvor Probleme mit dem Caching in NextJS und der Durchführung optimistischer Aktualisierungen, daher ist eine standardisierte Methode zur Erstellung optimistischer Aktualisierungen großartig, und ich bin mir sicher, dass dies der Fall sein wird Steigen Sie auf NextJS auf, falls dies noch nicht geschehen ist.

Die Verwendungs-API

Dies ist eine sehr dichte API und eine völlig neue Möglichkeit, auf Ressourcen zuzugreifen, während React eine Seite rendert – die genaue Formulierung lautet „Ressourcen beim Rendern lesen“. Wozu dient es also konkret? Diese neue API kann verwendet werden, um innerhalb von Bedingungen oder Schleifen auf Komponenteninformationen zuzugreifen. Wenn Sie nicht wissen, warum dies nützlich ist: Es hat damit zu tun, wie der Rendering-Prozess von React funktioniert. React/React-Fiber ist darauf angewiesen, alles jedes Mal in der gleichen Reihenfolge zu rendern, weshalb Sie während des Rendervorgangs im Allgemeinen nicht auf die meisten Hooks zugreifen können. Um es klarer auszudrücken: Der Status wird tatsächlich anhand der Reihenfolge verfolgt, in der Hooks aufgerufen werden. Wenn Hooks also in einer unvorhersehbaren Reihenfolge aufgerufen werden, kommt es zu Renderingfehlern. Ein gutes Beispiel ist der Zugriff auf einen Themenkontext, abhängig davon, ob der Benutzer angemeldet ist oder nicht.

Warum ist das eine wichtige Entwicklung? Das bedeutet, dass Sie Informationen/Daten nur dann laden können, wenn sie tatsächlich notwendig sind, z.B. Nur wenn ein Benutzer tatsächlich angemeldet ist, laden Sie CSS für ein spezielles Theme. Die Daten müssen serialisierbar sein, das heißt, Sie können ein Versprechen von der Serverkomponente an eine Clientkomponente senden, während diese tatsächlich bereits im Flug ist – das bedeutet, dass es weniger Wasserfallanforderungen gibt und diese automatisch parallel gestellt werden. Es ist erwähnenswert, dass Sie bei der Arbeit mit Serverkomponenten die Verwendung von async/await gegenüber der Verwendung für den Datenabruf bevorzugen sollten. Dies liegt daran, dass async/await das Rendern genau an der Stelle fortsetzt, an der es aufgehört hat, während die Verwendung ein vollständiges erneutes Rendern auslöst die Komponente, nachdem die Daten aufgelöst wurden. Natürlich möchte ich auch darauf hinweisen, dass diese Änderung tatsächlich auch bedeutet, dass Sie eine neue potenzielle Quelle für Wasserfallanfragen haben, wenn Sie die Verwendung falsch konfigurieren.

Eine wirklich wichtige Sache, die Sie beachten sollten, ist, dass Sie die „use“-API nicht in einem Try/Catch-Block verwenden können – das liegt daran, dass „use“ automatisch React-Suspense-Grenzen verwendet, wenn es mit einem Promise aufgerufen wird. Ein Try/Catch-Block verhindert, dass Sie jemals die React-Ebene erreichen, da jeder Fehler tatsächlich die Ausführung auf der JS-Ebene stoppen würde, bevor Sie React erreichen, wodurch die Funktionalität beeinträchtigt würde. Wie andere Hooks müssen sie sich auf der obersten Ebene des Gültigkeitsbereichs einer bestimmten Komponente oder Funktion befinden (wiederum aufgrund der Renderreihenfolge).

Der eigentliche Zweck der „Nutzung“ besteht also darin, Ihnen den Zugriff auf den Kontext zu erleichtern, um Dinge bedingt darzustellen und Daten nur dann abzurufen, wenn es tatsächlich notwendig ist. Dies ist ein weiterer Schritt, um die Reaktion etwas weniger geheimnisvoll zu gestalten, das Abrufen bedingter Daten zu vereinfachen, die Entwicklererfahrung zu verbessern und die Leistung auf einen Schlag zu verbessern. Es erfordert, dass erfahrenere React-Entwickler neu lernen, wie man Dinge wie Theming macht, aber ich denke, dass es das Framework für neue Benutzer viel zugänglicher macht, was immer großartig ist.

Neue React Dom Static APIs

Diese beiden neuen statischen APIs, prerender und prerenderToNodeStream, sind beide Verbesserungen von renderToString, das für Server Side Rendering (SSR) verwendet wird. Diese neuen Verbesserungen betreffen die statische Site-Generierung (SSG) mit renderToString. Im Gegensatz zu herkömmlichem Streaming-SSR, das Inhaltsblöcke senden kann, sobald diese verfügbar sind, warten diese neuen APIs speziell darauf, dass ALLE Daten geladen sind, bevor sie den endgültigen HTML-Code generieren. Sie sind so konzipiert, dass sie nahtlos mit modernen Streaming-Umgebungen wie Node.js Streams und Web Streams zusammenarbeiten, unterstützen jedoch absichtlich nicht das Streamen von Teilinhalten – stattdessen stellen sie sicher, dass Sie zum Zeitpunkt der Erstellung vollständige, vollständig geladene Seiten erhalten. Sie unterscheiden sich von herkömmlichen Streaming-SSR-Methoden, die vorgerenderte Websites senden, sobald Daten verfügbar sind.

Wir hatten bereits SSG-fähige Frameworks, die auf React aufbauten, wie NextJS, aber dies soll die native Funktionalität von React für SSG sein. Die Frameworks, die über SSG verfügten, verwendeten renderToString und bauten dann ihre eigenen komplexen Datenabrufkoordinationen darauf auf. Dies war für Benutzer äußerst schwierig selbst zu erstellen, und diese Frameworks verwendeten dazu äußerst komplexe Pipelines. Diese neuen Methoden ermöglichen im Wesentlichen das Laden von Daten während der statischen HTML-Generierung. Wenn Sie mit SSG nicht vertraut sind: Es rendert im Wesentlichen alles zur Erstellungszeit und ist zweifellos die schnellste Methode zum Rendern von Seiten, da dies nicht der Fall ist um Seiten auf Benutzeranfrage zu rendern. Daher ist es großartig, diese Art von Funktionalität für Leute zu haben, die etwas wie Next nicht verwenden möchten, was entweder eine Bereitstellung auf Vercel oder einen äußerst komplexen Bereitstellungsprozess erfordert.

Serverkomponenten

Das Konzept der React-Serverkomponenten wird für niemanden neu sein, der eine aktuelle Version von NextJS verwendet hat, aber für alle, die dies noch nicht getan haben, sind Serverkomponenten ein neues Paradigma rund um den Datenabruf. Ehrlich gesagt, das Konzept der Serverkomponenten (und Serveraktionen) verdient einen ganzen Artikel, aber um das Konzept kurz zusammenzufassen: Serverkomponenten werden immer auf dem Server gerendert, bevor sie an den Client gesendet werden, selbst nachdem Javascript geladen wurde. Das bedeutet, dass nachfolgende Renderings serverseitig erfolgen.

Der Hauptvorteil dieser Komponenten liegt in der Sicherheit und beim Datenabruf: Wenn Sie Daten innerhalb einer Serverkomponente anfordern, werden nie die Anforderungsinformationen auf der Clientseite angezeigt, sondern nur die Antwort, was sie wesentlich sicherer macht. APIs, Endpunkte usw. sind clientseitig einfach nicht zugänglich. Dadurch wird auch die Bundle-Größe reduziert, da das Javascript für diese Aktionen niemals an den Client gesendet wird. Darüber hinaus können Sie speicher- oder rechenintensive Vorgänge auf dem Server ausführen, um die Belastung durch das Rendern auf weniger leistungsstarken Computern zu verringern. Sie reduzieren auch clientseitige Wasserfälle, da der sequentielle Datenabruf auf Computern durchgeführt werden kann, die näher an Ihren Datenbanken liegen, aber es eröffnet natürlich auch die Möglichkeit völlig neuer serverseitiger Wasserfälle, da Ihre Entwickler den Zugriff auf einfache Anforderungsinformationen vom Testbrowser-Entwickler verlieren Tools und müssen so etwas wie einen OpenTelemetry-Sammler und -Viewer verwenden, um sie zu untersuchen. Schließlich eignen sich auch Serverkomponenten hervorragend für die progressive Erweiterung.

Serverkomponenten unterliegen außerdem einer Liste von Einschränkungen: Sie können keine lokalen Browser-APIs (lokaler Speicher, Fenster usw.) verwenden, React-Hooks funktionieren anders, Sie können sich nicht auf den Status verlassen oder ihn verwenden, und Sie können Da wir keine Event-Handler verwenden, ist die Benutzerinteraktivität für die Komponenten ausgesprochen gering. Stellen Sie sich dieses Paradigma im Grunde als Datenabruf in Serverkomponenten und Interaktivität in Clientkomponenten vor.

Der wichtigste Vorbehalt für alle, die mit Serverkomponenten noch nicht vertraut sind, besteht darin, dass Sie sie nicht in eine Clientkomponente importieren können. Wenn Sie dies tun, wird ein Fehler ausgegeben (vorausgesetzt, Sie haben einige Datenabrufe hinzugefügt), da der Compiler dies tun muss Serverkomponente als Clientkomponente. Wenn Sie eine Serverkomponente an eine Clientkomponente übergeben möchten, müssen Sie sie über die Requisite {children} übergeben.

Serveraktionen

Dies ist ein weiteres komplexes Thema mit vielen Auswirkungen darauf, wie Sie Ihre Produkte und Funktionen erstellen, und diese sind seit etwa einem Jahr auch in NextJS vorhanden. Serveraktionen werden durch die Eingabe von „Server verwenden“ am Anfang einer Datei deklariert und übergeben einen direkten Verweis auf die Serverfunktion, die dann innerhalb einer Clientkomponente aufgerufen werden kann.

In gewisser Hinsicht ähneln diese konzeptionell Remote Procedure Calls (RPC) – beide ermöglichen den Aufruf serverseitiger Funktionen vom Client aus, abstrahieren die Komplexität von Client-Server-Interaktionen und beide handhaben Serialisierung und Deserialisierung, aber Es gibt einige wichtige Unterschiede, die Sie beachten sollten. Der Hauptvorteil von Serveraktionen besteht darin, dass sie mit der progressiven Verbesserung von React zusammenarbeiten, zur Durchsetzung der Typsicherheit über Client-/Servergrenzen hinweg beitragen, über integrierte Leistungsoptimierungen (im Zusammenhang mit der progressiven Verbesserung) verfügen und eine nahtlosere Integration in das React-Ökosystem ermöglichen dadurch, dass sie integrierte ausstehende Status bereitstellen und automatisch in native Formularübermittlungen integriert werden.

Wenn es um modernes RPC geht, etwa gRPC, das bereits über Typsicherheit und einige Leistungsoptimierungen verfügt, liegt der Hauptvorteil von Serveraktionen im Allgemeinen in der integrierten Formularverarbeitung und progressiven Verbesserung, aber was noch wichtiger ist: Es funktioniert auch mit Reaktionsspannung und Fehlergrenzen. Am wichtigsten ist, dass die Bereitstellung viel einfacher ist, da Sie nicht unbedingt einen separaten Server für gRPC einrichten müssen. Daher sind diese besser für kleinere Projekte geeignet. Bei größeren Projekten sehe ich jedoch, dass gRPC seitdem viel wünschenswerter ist Es gibt Ihnen mehr Flexibilität in Bezug auf die Backend-Sprache usw.

Kontext als Anbieter

Dies ist im Wesentlichen eine Vereinfachung der Syntax, die dazu beiträgt, dass React im Allgemeinen eine viel sauberere, deklarative Syntax hat. Um ehrlich zu sein, kann ich dazu nicht viel sagen außer „Es gefällt mir“.

Ref als Requisite und Bereinigungsfunktionen für Refs

Früher mussten Sie zum Bereinigen von Referenzen eine Nullprüfung innerhalb Ihrer Komponente durchführen, und die Referenz wurde zu einem etwas unbestimmten Zeitpunkt bereinigt. React ruft Ihren Ref-Rückruf mit null auf, wenn die Komponente nicht gemountet wird, sodass Sie sowohl die Anhänge- als auch die Abtrennungsfälle explizit behandeln müssen. Der Vorteil der neuen Ref-Syntax ist die deterministische Bereinigung – was bedeutet, dass es jetzt viel einfacher ist, mit externen Ressourcen und Bibliotheken von Drittanbietern zu arbeiten, da Sie genau wissen, wann die Ref-Bereinigung erfolgt (beim Unmounten). Mit dem neuen Ansatz können Sie eine Bereinigungsfunktion direkt zurückgeben. Die TypeScript-Integration erfordert explizite Rückgabeanweisungen, um Unklarheiten über Bereinigungsfunktionen zu vermeiden.

Mir gefällt die Art und Weise, wie dies implementiert wurde, sehr gut, da es sich um das gleiche Muster von useEffect handelt – die Aufrechterhaltung der Konsistenz im gesamten Framework ist großartig. Ich denke, dass diese neue Ref-Bereinigung insbesondere für WebGL-Kontexte und andere umfangreiche Ressourcen sehr nützlich sein wird, aber auch für die Handhabung von DOM-Ereignis-Listenern, die mit nativen JS-Methoden hinzugefügt wurden. Dies liegt daran, dass React zuvor bei der Bereinigung den Verweis auf das dom-Element entfernt hat. Wenn Sie dies jedoch getan haben, wird es viel komplexer, Ereignis-Listener zu entfernen, da Sie den Verweis auf die Komponente verloren haben, an die sie angehängt sind . Infolgedessen mussten Sie Ihre Refs außerhalb des Elements speichern, was eine zusätzliche Komplexitätsebene hinzufügte. Jetzt können Sie Ereignis-Listener einfach aus der Rückgabefunktion Ihrer Komponente entfernen, da Sie weiterhin Zugriff auf den Verweis in der Rückgabefunktion haben. Dies bedeutet auch, dass wir uns in den meisten Situationen nicht mehr um den Null-Fall kümmern müssen, da React den Ref bei der Verwendung von Bereinigungsfunktionen nicht mehr mit Null aufruft. Die Bereinigungsfunktion selbst ersetzt diese Funktionalität und macht unseren Code sauberer und vorhersehbarer.

useDeferredValue

Der Zweck des useDeferredValue-Hooks besteht darin, rechenintensive Vorgänge zu verwalten und gleichzeitig eine reaktionsfähige Benutzeroberfläche aufrechtzuerhalten. Dies wird dadurch erreicht, dass Komponenten einen vorherigen „veralteten“ Wert anzeigen können, während im Hintergrund neue Daten berechnet oder abgerufen werden. Ein häufiger Anwendungsfall ist die Suchfunktion, die Ergebnisse anzeigt, während Benutzer tippen – ohne Verzögerung könnte jeder Tastendruck einen teuren Suchvorgang auslösen, der die Eingabe träge erscheinen lässt. Mit useDeferredValue kann die Schnittstelle reaktionsfähig bleiben, indem frühere Suchergebnisse angezeigt werden, während neue berechnet werden.

Diese neue Ergänzung ist eine wichtige Verbesserung des anfänglichen Ladeverhaltens dieses Hakens. Bisher wurde beim ersten Rendern sofort der Wert verwendet, der an useDeferredValue übergeben wurde, was möglicherweise gleich zu Beginn eine kostspielige Berechnung auslöste. Mit der neuen Version können Sie einen einfachen Anfangswert (z. B. eine leere Zeichenfolge) bereitstellen, der sofort angezeigt wird, während der teurere Wert im Hintergrund verarbeitet wird. Dies bedeutet, dass Sie Benutzern sofortiges Feedback mit einem sicheren Standardwert anzeigen und es dann mit echten Daten aktualisieren können, sobald die teure Berechnung abgeschlossen ist. Dies macht useDeferredValue im Wesentlichen noch besser für die Leistungsverbesserung.

Ergänzungen zu Dokumentmetadaten

Diese neuen Änderungen dienen dem Hinzufügen verschiedener Metadaten-Tags innerhalb tatsächlicher Komponenten. Sie gehen auf drei Optionen ein: , und <meta>. Es ist wichtig zu beachten, dass <title> hat keine Deduplizierung – Sie sollen es nur einmal pro Repo verwenden. Die anderen beiden, <link> und <meta> haben einige ziemlich komplexe Interaktionen in Bezug auf die Deduplizierung, die meiner Meinung nach für 90 % der Benutzer nicht besonders relevant sein werden, nachdem ich sie kennengelernt habe. </p> <p>Der Hauptvorteil dieser Änderungen besteht darin, dass sie es den Komponenten ermöglichen, wirklich in sich geschlossen zu sein: Sie können jetzt ihre eigenen Metadaten zusammen mit ihren Stilen und Skripten verwalten. Sie müssen nicht mehr herausfinden, wie Sie Metadaten auf die oberste Ebene bringen, oder dafür eine Bibliothek verwenden, was SEO viel einfacher macht. Verschiedene Seiten in einem SPA können einfacher unterschiedliche Metadaten haben, ohne dass die Gefahr besteht, dass die Metadaten nicht mehr mit dem auf der Seite angezeigten Inhalt synchron sind, was früher ein Risiko darstellte, wenn unterschiedliche Metadaten für verschiedene Seiten vorhanden waren.</p> <p><strong>Stylesheet-Unterstützung</strong></p> <p>Die Leute verwenden Rückenwind vielleicht schon so lange, dass sie es vergessen haben, aber die Ausführung von nicht gekapseltem CSS kann aufgrund der Art und Weise, wie Stylesheets geladen werden, zu Problemen führen – nämlich den Prioritätsregeln für die Ladereihenfolge. Erstens kann es zu Blitzen von nicht formatiertem Inhalt kommen – jedes Mal, wenn der HTML-Code geladen und gerendert wird, bevor das CSS heruntergeladen wurde, wird er als komplett weiße Seite angezeigt, normalerweise in einer einzelnen Spalte mit riesigen Schriftgrößen und nativen Bildgrößen, was oft der Fall ist macht es unlesbar.</p> <p>Darüber hinaus können Regeln für die Ladereihenfolge von CSS zu anderen Problemen führen: Wenn Sie beispielsweise Regeln mit derselben Spezifität haben, aber erwarten, dass sie in einer bestimmten Reihenfolge geladen werden. Dies ist beispielsweise relevant, wenn Sie verschiedene Optionen für Themen haben (z. B. Dunkelmodus). Wenn das CSS für den dunklen Modus zuletzt geladen werden soll, Ihre CSS-Datei für den dunklen Modus jedoch zuerst geladen wird, kann es sein, dass der dunkle Modus hell ist oder einige Teile der App, in denen die Regeln eingehalten werden, und andere Teile, in denen sie eingehalten werden. t eingehalten. </p> <p>Es gab viele Lösungen, um dies zu vermeiden, wie z. B. CSS in JS, bei dem das gesamte CSS in den <head> geladen wird. Tag, Erstellungszeit, die CSS zusammenbündelt usw. Diese neuen CSS-Änderungen sollen jedoch dabei helfen, diese Probleme zu bewältigen, indem sie deklarativ die Priorität festlegen – sie stellen außerdem sicher, dass alle in einer Komponente platzierten Stylesheets geladen werden, bevor die Komponente selbst gerendert wird. Es verfügt außerdem über eine integrierte Deduplizierung, sodass Sie nicht dasselbe Stylesheet mehrmals laden müssen, wenn Sie Komponenten mit enthaltenen Stylesheet-Links wiederverwenden. </p> <p>Der Zugriff auf diese neue Funktionalität (Warten auf das Laden des CSS vor dem Rendern einer Komponente, automatisches Hochziehen von CSS in den Kopf usw.) ist ebenfalls ziemlich einfach – Sie müssen lediglich eine Priorität in einen bestimmten <Link> einfügen ; Komponente. Im Großen und Ganzen bin ich ein Typoskript-Genießer, daher geht es für mich nicht unbedingt auf bestimmte Probleme ein, aber ich bin mir sicher, dass dies äußerst nützliche große Legacy-Projekte sein werden. </p> <p><strong>Unterstützung für asynchrone Skripte</strong></p> <p>Hiermit wird ein Grenzfall adressiert, im Gegensatz zur Schaffung einer neuen Kernfunktionalität, über die sich die Leute Sorgen machen müssen – das manuelle Hinzufügen/direkte Verwalten von Skripten mit einem <script> Tag ist meiner Erfahrung nach im modernen React ziemlich selten. Die meisten Entwickler verwenden Bundler wie Webpack oder Vite, Paketmanager und Importanweisungen, und wenn Skripte dynamisch geladen werden müssen, verwenden sie etwas wie useEffect. Dies ist jedoch für SSR und besseres UX relevant, um die oben genannten Probleme mit der Ladereihenfolge der Inhalte im <head> zu vermeiden. </p> <p>Da Skripte asynchron geladen werden können, ist die Wahrscheinlichkeit, dass React-Apps ohne geeignete Stile geladen werden, deutlich geringer. Die Änderung ist auch für Entwickler relevant, die Legacy-Systeme verwalten, die direkte Skript-Tags erfordern, oder für Entwickler, die für die Verwaltung von Drittanbieter-Skripten verantwortlich sind, die nicht gebündelt werden können (z. B. Analysen, Widgets usw.) oder die ein besonders umfangreiches Skript (z. B. ein Video) verhindern (Player) laden, bevor die Leistung verbessert werden muss, aber da ich damit keine Erfahrung habe, kann ich dazu nicht viel mehr sagen. </p> <p><strong>Unterstützung für das Vorladen von Ressourcen</strong></p> <p>Die neuen APIs zur Verwaltung des Ressourcen-Vorladens sind sehr interessant, insbesondere für größere Unternehmen, die nahtlose Ladeerlebnisse für globale Zielgruppen mit stark variierenden Netzwerkbedingungen gewährleisten müssen, für besonders inhaltsintensive Apps, die auf umfangreiche Ressourcen Dritter aus verschiedenen Quellen angewiesen sind , und für jede App, bei der die wahrgenommene Leistung für die Benutzerbindung wichtig ist (was, um ehrlich zu sein, fast alles ist) </p> <p>Allerdings haben die meisten Frameworks, die auf React basieren (z. B. Next, Remix usw.), dies in der Regel bereits geschafft – ich bin mir nicht ganz sicher, wie diese neuen APIs mit diesen Frameworks interagieren werden, aber es scheint so zu sein. Dies stellt eine neue Quelle für Konflikte dar und ist etwas Wichtiges, das Sie im Hinterkopf behalten sollten, wenn Sie diese Frameworks verwenden und versuchen, die Leistung mithilfe dieser neuen APIs zu optimieren. </p> <p>Während Preload definitiv die API mit dem umfassendsten Anwendungsfall ist (Laden von Stylesheets usw.), ist Preinit meiner Meinung nach aufgrund des oben genannten Problems die API mit der größten Relevanz – es handelt sich um einen Hardload, der sofort startet und zum eifrigen Laden gedacht ist Skripte. Die offensichtlichste Verwendung, die mir einfällt, ist so etwas wie das sofortige Laden von Stripe bei der Überprüfung des Warenkorbs – dies sollte den Checkout-Prozess erheblich beschleunigen, was ein Schritt im E-Commerce ist, bei dem man auf keinen Fall Kunden aufgrund von Leistungsproblemen verlieren möchte . </p> <p><strong>Kompatibilität mit Skripten von Drittanbietern</strong></p> <p>Dies ist eine sehr willkommene Änderung angesichts der zunehmenden Verbreitung von Browser-Add-Ons. Ich kann mir einige Beispiele für die geänderte DOM-Struktur vorstellen, die wahrscheinlich von dieser Änderung profitieren, sind Werbeblocker, Preisvergleichstools, Grammatik-/KI-Assistenten-Add-Ons und Übersetzungserweiterungen . Dazu gibt es nicht viel mehr zu sagen, ohne tatsächlich zu lesen, wie die Hydratation jetzt funktioniert, obwohl die wichtigste Änderung anscheinend darin besteht, dass der Compiler unerwartete Tags überspringt. </p> <p><strong>Bessere Fehlerberichterstattung</strong></p> <p>Ich fand diesen Abschnitt ziemlich selbsterklärend. Änderungen bei der Fehlerbehandlung sind immer willkommen – der frühere Fehler-Spam machte es immer etwas schwieriger, bestimmte Fehler aufzuspüren. Dies ist besonders relevant, wenn Sie weniger gut gewartete Lösungen von Drittanbietern verwenden, die dazu neigen, eine Menge Fehler auszulösen.<br> Unterstützung für benutzerdefinierte Elemente</p> <p>Dieser Abschnitt war für mich besonders interessant, da ich noch nie von Custom Elements gehört hatte. Zusammenfassend lässt sich sagen, dass es sich bei benutzerdefinierten Elementen um einen neuen Webstandard handelt, mit dem Entwickler ihre eigenen HTML-Elemente erstellen können. Dank der Einhaltung dieser Webstandards sollen sie auf jeder Seite funktionieren und Framework-unabhängig sein – Sie könnten beispielsweise eine Komponente schreiben, die Sie häufig in all Ihren persönlichen Projekten verwenden, was Sie normalerweise in Svelte tun, und sie dann für kleinere verwenden Vertragsarbeit, die Sie für Start-ups erledigen, oder kurzfristige Verträge in Vue usw. </p> <p>React behandelte früher nicht erkannte Requisiten als Attribute statt als tatsächliche Eigenschaften – das neue Update hat ein System hinzugefügt, das die ordnungsgemäße Verwendung von Requisiten zum Erstellen benutzerdefinierter Elemente ermöglicht. Es scheint, dass es mit dieser Änderung nun volle Unterstützung für die Verwendung benutzerdefinierter Elemente in React gibt. Nebenbei bemerkt, zusätzlich zum Requisitenproblem gab es früher auch Inkompatibilitäten (jetzt behoben) mit dem synthetischen Ereignissystem von React – benutzerdefinierte Elemente konnten nicht sauber in das System integriert werden, daher gab es einige Fälle, in denen man es tatsächlich manuell tun musste Fügen Sie unter anderem Ereignis-Listener mit ref hinzu. </p> <p>Das obige ist der detaillierte Inhalt vonReact Update Notes Companion. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!</p></div><div class="nphpQianMsg"><a href="javascript:void(0);">JavaScript</a> <a href="javascript:void(0);">typescript</a> <a href="javascript:void(0);">css</a> <a href="javascript:void(0);">less</a> <a href="javascript:void(0);">html</a> <a href="javascript:void(0);">edge</a> <a href="javascript:void(0);">webpack</a> <a href="javascript:void(0);">Static</a> <a href="javascript:void(0);">String</a> <a href="javascript:void(0);">Boolean</a> <a href="javascript:void(0);">Array</a> <a href="javascript:void(0);">Object</a> <a href="javascript:void(0);">NULL</a> <a href="javascript:void(0);">Resource</a> <a href="javascript:void(0);">if</a> <a href="javascript:void(0);">for</a> <a href="javascript:void(0);">while</a> <a href="javascript:void(0);">include</a> <a href="javascript:void(0);">require</a> <a href="javascript:void(0);">try</a> <a href="javascript:void(0);">catch</a> <a href="javascript:void(0);">Error</a> <a href="javascript:void(0);">register</a> <a href="javascript:void(0);">using</a> <a href="javascript:void(0);">Interface</a> <a href="javascript:void(0);">Conditional</a> <a href="javascript:void(0);">Event</a> <a href="javascript:void(0);">var</a> <a href="javascript:void(0);">JS</a> <a href="javascript:void(0);">function</a> <a href="javascript:void(0);">default</a> <a href="javascript:void(0);">dom</a> <a href="javascript:void(0);">this</a> <a href="javascript:void(0);">promise</a> <a href="javascript:void(0);">display</a> <a href="javascript:void(0);">background</a> <a href="javascript:void(0);">animation</a> <a href="javascript:void(0);">column</a> <a href="javascript:void(0);">input</a> <a href="javascript:void(0);">kind</a> <a href="javascript:void(0);">rpc</a> <a href="javascript:void(0);">ux</a> <a href="javascript:void(0);">issue</a> <a href="javascript:void(0);">webgl</a> <a href="javascript:void(0);">everything</a> <a href="javascript:void(0);">Access</a> <a href="javascript:void(0);">SEO</a> <a href="javascript:void(0);">Other</a><div class="clear"></div></div><div class="nphpQianSheng"><span>Stellungnahme:</span><div>Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn</div></div></div><div class="nphpSytBox"><span>Vorheriger Artikel:<a class="dBlack" title="Erstellen eines KI-gestützten Hintergrundentferners mit React und Transformers.js" href="https://m.php.cn/de/faq/1796752021.html">Erstellen eines KI-gestützten Hintergrundentferners mit React und Transformers.js</a></span><span>Nächster Artikel:<a class="dBlack" title="Erstellen eines KI-gestützten Hintergrundentferners mit React und Transformers.js" href="https://m.php.cn/de/faq/1796752027.html">Erstellen eines KI-gestützten Hintergrundentferners mit React und Transformers.js</a></span></div><div class="nphpSytBox2"><div class="nphpZbktTitle"><h2>In Verbindung stehende Artikel</h2><em><a href="https://m.php.cn/de/article.html" class="bBlack"><i>Mehr sehen</i><b></b></a></em><div class="clear"></div></div><ins class="adsbygoogle" style="display:block" data-ad-format="fluid" data-ad-layout-key="-6t+ed+2i-1n-4w" data-ad-client="ca-pub-5902227090019525" data-ad-slot="8966999616"></ins><script> (adsbygoogle = window.adsbygoogle || []).push({}); </script><ul class="nphpXgwzList"><li><b></b><a href="https://m.php.cn/de/faq/1609.html" title="Eine eingehende Analyse der Bootstrap-Listengruppenkomponente" class="aBlack">Eine eingehende Analyse der Bootstrap-Listengruppenkomponente</a><div class="clear"></div></li><li><b></b><a href="https://m.php.cn/de/faq/1640.html" title="Detaillierte Erläuterung des JavaScript-Funktions-Curryings" class="aBlack">Detaillierte Erläuterung des JavaScript-Funktions-Curryings</a><div class="clear"></div></li><li><b></b><a href="https://m.php.cn/de/faq/1949.html" title="Vollständiges Beispiel für die Generierung von JS-Passwörtern und die Erkennung der Stärke (mit Download des Demo-Quellcodes)" class="aBlack">Vollständiges Beispiel für die Generierung von JS-Passwörtern und die Erkennung der Stärke (mit Download des Demo-Quellcodes)</a><div class="clear"></div></li><li><b></b><a href="https://m.php.cn/de/faq/2248.html" title="Angularjs integriert WeChat UI (weui)" class="aBlack">Angularjs integriert WeChat UI (weui)</a><div class="clear"></div></li><li><b></b><a href="https://m.php.cn/de/faq/2351.html" title="Wie man mit JavaScript schnell zwischen traditionellem Chinesisch und vereinfachtem Chinesisch wechselt und wie Websites den Wechsel zwischen vereinfachtem und traditionellem Chinesisch unterstützen – Javascript-Kenntnisse" class="aBlack">Wie man mit JavaScript schnell zwischen traditionellem Chinesisch und vereinfachtem Chinesisch wechselt und wie Websites den Wechsel zwischen vereinfachtem und traditionellem Chinesisch unterstützen – Javascript-Kenntnisse</a><div class="clear"></div></li></ul></div></div><ins class="adsbygoogle" style="display:block" data-ad-format="autorelaxed" data-ad-client="ca-pub-5902227090019525" data-ad-slot="5027754603"></ins><script> (adsbygoogle = window.adsbygoogle || []).push({}); </script><footer><div class="footer"><div class="footertop"><img src="/static/imghwm/logo.png" alt=""><p>Online-PHP-Schulung für das Gemeinwohl,Helfen Sie PHP-Lernenden, sich schnell weiterzuentwickeln!</p></div><div class="footermid"><a href="https://m.php.cn/de/about/us.html">Über uns</a><a href="https://m.php.cn/de/about/disclaimer.html">Haftungsausschluss</a><a href="https://m.php.cn/de/update/article_0_1.html">Sitemap</a></div><div class="footerbottom"><p> © php.cn All rights reserved </p></div></div></footer><script>isLogin = 0;</script><script type="text/javascript" src="/static/layui/layui.js"></script><script type="text/javascript" src="/static/js/global.js?4.9.47"></script></div><script src="https://vdse.bdstatic.com//search-video.v1.min.js"></script><link rel='stylesheet' id='_main-css' href='/static/css/viewer.min.css' type='text/css' media='all'/><script type='text/javascript' src='/static/js/viewer.min.js?1'></script><script type='text/javascript' src='/static/js/jquery-viewer.min.js'></script><script>jQuery.fn.wait = function (func, times, interval) { var _times = times || -1, //100次 _interval = interval || 20, //20毫秒每次 _self = this, _selector = this.selector, //选择器 _iIntervalID; //定时器id if( this.length ){ //如果已经获取到了,就直接执行函数 func && func.call(this); } else { _iIntervalID = setInterval(function() { if(!_times) { //是0就退出 clearInterval(_iIntervalID); } _times <= 0 || _times--; //如果是正数就 -- _self = $(_selector); //再次选择 if( _self.length ) { //判断是否取到 func && func.call(_self); clearInterval(_iIntervalID); } }, _interval); } return this; } $("table.syntaxhighlighter").wait(function() { $('table.syntaxhighlighter').append("<p class='cnblogs_code_footer'><span class='cnblogs_code_footer_icon'></span></p>"); }); $(document).on("click", ".cnblogs_code_footer",function(){ $(this).parents('table.syntaxhighlighter').css('display','inline-table');$(this).hide(); }); $('.nphpQianCont').viewer({navbar:true,title:false,toolbar:false,movable:false,viewed:function(){$('img').click(function(){$('.viewer-close').trigger('click');});}}); </script></body><!-- Matomo --><script> var _paq = window._paq = window._paq || []; /* tracker methods like "setCustomDimension" should be called before "trackPageView" */ _paq.push(['trackPageView']); _paq.push(['enableLinkTracking']); (function() { var u="https://tongji.php.cn/"; _paq.push(['setTrackerUrl', u+'matomo.php']); _paq.push(['setSiteId', '9']); var d=document, g=d.createElement('script'), s=d.getElementsByTagName('script')[0]; g.async=true; g.src=u+'matomo.js'; s.parentNode.insertBefore(g,s); })(); </script><!-- End Matomo Code --></html>