Heim > Web-Frontend > js-Tutorial > Umgang mit asynchronen APIs in servergerenderten React

Umgang mit asynchronen APIs in servergerenderten React

William Shakespeare
Freigeben: 2025-02-16 11:52:10
Original
745 Leute haben es durchsucht

Dealing with Asynchronous APIs in Server-rendered React

Zusammenfassung der Schlüsselpunkte

  • serverseitiges Rendering von React-Code hilft bei der Verringerung der Ladezeiten und der Verbesserung der SEO-Flexibilität. Die Behandlung von asynchronen APIs kann jedoch eine Herausforderung darstellen, da die Anwendung die Anwendung rendert, bevor Sie die erforderlichen Daten kennen.
  • vorhandene Lösungen wie Next.js, Redux Connect und React-Frontload haben ihre eigenen Vor- und Nachteile, wenn sie sich mit asynchronen APIs im serverten React-Code befassen.
  • benutzerdefinierte Lösungen können durch Durchführung von zwei serverseitigen Renderings implementiert werden: Das erste Mal wird API-Aufrufe und asynchrone Vorgänge behandelt, und das zweite Mal verwendet die erfassten Daten für die endgültige Rendern der Seite.
  • Anpassungslösungen erfordern eine sorgfältige Handhabung verschiedener Zustände in der Komponente, einschließlich Vorabklingungs-, Postfetch-, Vorrender- und Back-End-Rendering. Dies kann durch Komplexe erreicht werden, wenn Anweisungen im Komponentencode.
  • benutzerdefinierte Lösungen müssen auch die Datei index.html ändern, um vorgeholkte Daten als Teil der Seitenanforderung zu senden und sie zum Durchsuchen und Ersetzen hinzuzufügen. Wenn Sie Skript-Tags verwenden, benötigen Sie Basis-64-Codierung.

Wenn Sie jemals eine grundlegende React -App -Seite erstellt haben, kann sie schlechte SEO- und Leistungsprobleme haben, insbesondere auf langsameren Geräten. Sie können traditionelle Webserver -Rendering hinzufügen (normalerweise mit NodeJS), dies ist jedoch kein einfacher Prozess, insbesondere bei der Behandlung asynchroner APIs.

Die beiden Hauptvorteile des serverseitigen Rendering-Codes sind:

  • Beschleunigen Sie die Ladegeschwindigkeit
  • SEO -Flexibilität verbessert

Denken Sie daran, dass Google darauf wartet, dass Ihr JavaScript geladen wird, so dass sich einfache Inhalte wie den Titelinhalt ohne Probleme ändern. (Ich kann jedoch nicht sagen, was mit anderen Suchmaschinen passiert oder wie zuverlässig das ist.)

In diesem Artikel werde ich diskutieren, wie Sie Daten von einer asynchronen API erhalten, wenn Sie den Server-React-Code verwenden. React Code verfügt über eine gesamte Anwendungsstruktur in JavaScript. Dies bedeutet, dass Sie im Gegensatz zum herkömmlichen MVC -Modus mit Controllern nicht wissen, welche Daten Sie benötigen, bevor die Anwendung rendert. Mit einem Framework wie React-App erstellen können Sie schnell qualitativ hochwertige Arbeitsanwendungen erstellen. Sie müssen jedoch nur auf der Client-Seite verarbeiten. Dies hat Leistungsprobleme sowie SEO/Datenprobleme, bei denen Sie den Header nach Bedarf ändern können.

Frage

reagieren hauptsächlich das Rendering synchronisiert. Wenn Sie also keine Daten haben, wird der Ladebildschirm gerendert und auf die Ankunft der Daten warten. Dies funktioniert auf der Serverseite nicht gut, da Sie vor dem Rendern nicht wissen, was Sie benötigen, oder Sie wissen, was Sie brauchen, aber Sie haben es gemacht.

Zeigen Sie diese Standard -Rendering -Methode an:

ReactDOM.render(
  <provider> store={store}></provider>
    <browserrouter></browserrouter>
      <app></app>
    >
  >
, document.getElementById('root')
)
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren

Frage:

  1. Dies ist eine DOM -Rendering, die nach Wurzelelementen sucht. Dies existiert nicht auf meinem Server, daher müssen wir es trennen.
  2. Wir können nicht außerhalb des Hauptwurzelelements auf etwas zugreifen. Wir können Facebook -Tags, Titel, Beschreibungen, verschiedene SEO -Tags nicht festlegen und den Rest des DOM außerhalb des Elements, insbesondere der Header, nicht kontrollieren.
  3. Wir stellen einige Zustände an, aber der Server und der Client haben unterschiedliche Zustände. Wir müssen überlegen, wie wir mit diesem Zustand umgehen sollen (in diesem Fall Redux).

Ich habe hier zwei Bibliotheken verwendet und sie sind sehr beliebt, daher kann es hoffentlich auf andere von Ihnen verwendete Bibliotheken angewendet werden.

Redux: Der Status des Speicherservers und der Client -Synchronisation ist ein Albtraumproblem. Es ist sehr teuer und führt oft zu komplexen Fehlern. Auf der Serverseite möchten Sie im Idealfall nichts mit Redux tun, außer dass es ausreicht, damit die Dinge funktionieren und richtig rendern. (Sie können es weiterhin wie gewohnt verwenden. Stellen Sie nur genug Status fest, damit es wie ein Kunde aussieht.) Wenn Sie es versuchen möchten, lesen Sie die verschiedenen verteilten Systemführer als Ausgangspunkt.

React-Router: FYI, dies ist die V4-Version, die die Standardversion ist, aber sie ist sehr unterschiedlich, wenn Sie ein älteres vorhandenes Projekt haben. Sie müssen sicherstellen, dass Sie das Routing auf der Serverseite und auf der Client -Seite verarbeiten und v4 verwenden - es ist in dieser Hinsicht hervorragend.

Was ist, wenn Sie einen Datenbankanruf tätigen müssen? Dies wird plötzlich zu einem großen Problem, da es asynchron ist und sich in Ihrer Komponente befindet. Dies ist natürlich keine neue Frage: Betrachten Sie sie im offiziellen React -Repository.

Sie müssen rendern, um festzustellen, welche Abhängigkeiten benötigt werden - diese Abhängigkeiten müssen zur Laufzeit festgelegt werden - und um diese Abhängigkeiten zu erhalten, bevor sie dem Kunden zur Verfügung gestellt werden.

vorhandene Lösungen

unten werde ich die derzeit bereitgestellten Lösungen für dieses Problem überprüfen.

next.js

Bevor wir beginnen, ist Next.js ideal für Sie, wenn Sie serverseitige React-Code oder universelle Anwendung für Ihre Produktionsumgebung wünschen. Es ist effektiv, prägnant und hat Zeit für Zeit.

Es ist jedoch der Meinung, dass Sie ihre Toolchain verwenden müssen, und die Art und Weise, wie sie mit asynchronem Datenladen umgehen, ist nicht unbedingt flexibel.

Diese direkte Kopie des Inhalts im nächsten.js Repository -Dokument anzeigen:

ReactDOM.render(
  <provider> store={store}></provider>
    <browserrouter></browserrouter>
      <app></app>
    >
  >
, document.getElementById('root')
)
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren

getInitialProps ist der Schlüssel, es wird ein Versprechen zurückgegeben, das sich auf ein mit Requisiten gefüllter Objekt entscheidet und nur auf der Seite ist. Das Beste von allen ist, dass dies nur in ihre Toolchain integriert ist: Fügen Sie es ohne Arbeit hinzu, um zu arbeiten!

Wie erhalten Sie Datenbankdaten? Sie machen einen API -Anruf. Du willst nicht? Ok, das ist schrecklich. (Okay, Sie können benutzerdefinierte Inhalte hinzufügen, müssen ihn jedoch selbst vollständig implementieren.) Wenn Sie darüber nachdenken, ist dies jedoch eine sehr vernünftige und allgemein gute Praxis und die Latenz auf dem Server ist fast vernachlässigbar.

Was Sie auch zugreifen können, ist begrenzt - fast nur das Anforderungsobjekt. Oh, und wenn Sie es noch nicht bemerkt haben, funktioniert es nur mit Seitenkomponenten auf der Spitze.

Redux Connect

Redux Connect ist ein sehr eindeutiger Server-Seite mit einer schönen Idee, aber dies ist möglicherweise nicht für Sie, wenn Sie nicht alle Tools verwenden, die sie beschreiben. Dieses Paket enthält viele Inhalte, ist aber sehr komplex und wurde nicht auf den Reagieren von Router V4 aufgerüstet. Es gibt viele Einstellungen, aber schauen wir uns den wichtigsten Teil an, nur um einige Lektionen zu lernen:

ReactDOM.render(
  <provider> store={store}></provider>
    <browserrouter></browserrouter>
      <app></app>
    >
  >
, document.getElementById('root')
)
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren

Dekorateure sind in JavaScript nicht Standard. Zum Zeitpunkt des Schreibens befinden sie sich in Phase 2, also verwenden Sie mit Vorsicht. Dies ist nur eine weitere Möglichkeit, Komponenten höherer Ordnung hinzuzufügen. Die Idee ist einfach: Der Schlüssel ist, was an Ihre Requisiten übergeben wird, und dann haben Sie eine Reihe von Versprechen, die analysieren und weitergeben. Das sieht gut aus. Vielleicht ist eine weitere Option Folgendes:

import React from 'react'
export default class extends React.Component {
  static async getInitialProps ({ req }) {
    return req
      ? { userAgent: req.headers['user-agent'] }
      : { userAgent: navigator.userAgent }
  }
  render () {
    return <div>
      Hello World {this.props.userAgent}
    </div>
  }
}
Nach dem Login kopieren
Nach dem Login kopieren

Dies kann mit JavaScript ohne allzu viele Probleme erfolgen.

reagieren Sie die Front-Load

Das React-Front-Load-Repository enthält nicht viele Dokumentationen oder Erklärungen, aber das beste Verständnis, das ich erhalten kann, kann aus dem Test (wie diesem) und dem Lesen des Quellcodees kommen. Wenn etwas montiert ist, wird es der Versprechen -Warteschlange hinzugefügt, und wenn die Warteschlange analysiert wird, wird es serviert. Was es tut ist sehr gut, obwohl es schwierig ist, etwas zu empfehlen, das nicht gut dokumentiert, gewartet oder verwendet wird:

// 1. 连接您的数据,类似于 react-redux @connect
@asyncConnect([{
  key: 'lunch',
  promise: ({ params, helpers }) => Promise.resolve({ id: 1, name: 'Borsch' })
}])
class App extends React.Component {
  render() {
    // 2. 将数据作为 props 访问
    const lunch = this.props.lunch
    return (
      <div>{lunch.name}</div>
    )
  }
}
Nach dem Login kopieren
Nach dem Login kopieren

Auf der Suche nach besseren Lösungen

Keine der oben genannten Lösungen entspricht wirklich zu meinen Erwartungen für die Flexibilität und Einfachheit der Bibliothek, daher werde ich nun meine eigene Implementierung einführen. Das Ziel ist nicht, Pakete zu schreiben, sondern Ihnen eine Vorstellung davon zu geben, wie Sie Ihre eigenen Pakete basierend auf Ihrem Anwendungsfall schreiben.

Das Repository dieser Beispiellösung befindet sich hier.

Theorie

Die Idee dahinter ist relativ einfach, obwohl sie irgendwann eine Menge Code erzeugen wird. Dies soll die Ideen beschreiben, über die wir diskutieren.

Der Server muss den React -Code zweimal rendern, und wir werden dafür nur renderToString verwenden. Wir wollen den Kontext zwischen dem ersten und dem zweiten Renderings halten. In unserem ersten Rendern haben wir versucht, API -Anrufe, Versprechen und asynchrone Operationen zu beseitigen. In unserem zweiten Render möchten wir alle Daten, die wir erhalten, in unseren Kontext zurücklegen und unsere Arbeitsseite für die Verteilung rendern. Dies bedeutet auch, dass der Anwendungscode Aktionen basierend auf dem Kontext (oder nicht der Ausführung von Vorgängen) ausführen muss, z. B. ob er sich auf dem Server oder auf dem Browser befindet, und in beiden Fällen, ob die Daten abgerufen werden.

Zusätzlich können wir es nach Bedarf anpassen. In diesem Fall ändern wir den Statuscode und den Header entsprechend dem Kontext.

zuerst Rendering

In Ihrem Code müssen Sie wissen, ob Sie am Server oder auf dem Browser arbeiten. Idealerweise möchten Sie eine komplexe Kontrolle darüber. Mit React Router können Sie eine statische Kontext -Requisite erhalten, die großartig ist, also werden wir sie verwenden. Derzeit fügen wir nur ein Datenobjekt hinzu und fordern Daten an, wie wir von Next.js. Unsere APIs variieren zwischen Server und Client, sodass Sie eine Server -API bereitstellen müssen, die besser eine ähnliche Schnittstelle wie Ihre Client -API hat:

ReactDOM.render(
  <provider> store={store}></provider>
    <browserrouter></browserrouter>
      <app></app>
    >
  >
, document.getElementById('root')
)
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren

zweites Render

Nach dem ersten Rendering werden wir diese anhängigen Versprechen erhalten und darauf warten, dass diese Versprechen abgeschlossen, dann erneut rendern, den Kontext aktualisieren:

import React from 'react'
export default class extends React.Component {
  static async getInitialProps ({ req }) {
    return req
      ? { userAgent: req.headers['user-agent'] }
      : { userAgent: navigator.userAgent }
  }
  render () {
    return <div>
      Hello World {this.props.userAgent}
    </div>
  }
}
Nach dem Login kopieren
Nach dem Login kopieren

App

Springen Sie schnell von unserem Server zum Anwendungscode: In einer unserer Komponenten mit Router -Verbindungen können wir ihn jetzt erhalten:

// 1. 连接您的数据,类似于 react-redux @connect
@asyncConnect([{
  key: 'lunch',
  promise: ({ params, helpers }) => Promise.resolve({ id: 1, name: 'Borsch' })
}])
class App extends React.Component {
  render() {
    // 2. 将数据作为 props 访问
    const lunch = this.props.lunch
    return (
      <div>{lunch.name}</div>
    )
  }
}
Nach dem Login kopieren
Nach dem Login kopieren

wow, es gibt viele komplizierte Code. In diesem Stadium möchten Sie möglicherweise einen weiteren Ansatz verfolgen, bei dem Sie den Datenabrufcode in eine andere Komponente trennen.

Diese Komponente besteht aus Komponenten, mit denen Sie möglicherweise vertraut sind - Schritte und componentWillMount Schritte. Vierstufig, wenn Aussagen verschiedene Zustände behandeln-Prefetch-, Postfetch-, Pre-Render- und Back-End-Rendering. Wir fügen die Daten auch zum Header hinzu, nachdem sie geladen wurde.

Schließlich gibt es einen weiteren Schritt, um die Daten zu erhalten. Idealerweise haben Ihre API und Ihre Datenbank die gleiche API, was die Ausführung gleich macht. Möglicherweise möchten Sie diese in Aktionen in Thunk oder Saga aufnehmen, um sie skalierbarer zu machen.

Zeigen Sie den Artikel "Server React Rendering" und "Repository React Server Rendering" für weitere Informationen. Denken Sie daran, dass Sie den Zustand, in dem die Daten nicht geladen sind, noch verarbeiten müssen! Sie werden beim ersten Laden nur das Server-Side-Rendering durchführen, sodass Sie den Ladebildschirm auf nachfolgenden Seiten anzeigen.

index.html ändern, um Daten

hinzuzufügen

Wir müssen alle vorgeholkten Daten als Teil der Seitenanforderung senden, damit wir ein Skript -Tag hinzufügen:

@asyncConnect([{
  lunch: ({ params, helpers }) => Promise.resolve({ id: 1, name: 'Borsch' })
}])
Nach dem Login kopieren

Service

Dann müssen wir es zu unserer Suche und unserem Austausch hinzufügen. HTML verwendet jedoch einen sehr grundlegenden Skript-Tag-Finder. Wenn Sie also Skript-Tags haben, müssen Sie es Basis-64 codieren. Vergiss auch nicht unsere Kopfetiketten!

const App = () => (
  <frontload>isServer</frontload>
    <component1> entityId='1' store={store}></component1>
  >
)

return frontloadServerRender(() => (
  render(<app></app>)
)).then((serverRenderedMarkup) => {
  console.log(serverRenderedMarkup)
})
Nach dem Login kopieren

Wir verarbeiten auch Statuscodeänderungen - beispielsweise für 404 -, wenn Sie also eine 404 -Seite haben, können Sie dies tun:

const context = {data: {}, head: [], req, api}
const store = configureStore()
renderToString(
  <provider> store={store}></provider>
    <staticrouter> location={req.url} context={context}>
      <app></app>
    >
  >
)
Nach dem Login kopieren

Zusammenfassung

Wenn Sie nicht sicher sind, was Sie tun, verwenden Sie einfach Next.js. Es ist für serverseitige Rendering und universelle Anwendungen ausgelegt. Wenn Sie die Flexibilität wünschen, alles manuell zu tun, können Sie es so tun, wie Sie es möchten. Zu einem Beispiel gehört möglicherweise, dass Sie Daten abrufen, die in einer untergeordneten Komponente abrufen, anstatt auf Seitenebene.

Ich hoffe, dieser Artikel kann Ihnen helfen, loszulegen! Vergessen Sie nicht, das Github -Repository für eine praktikable Implementierung zu überprüfen.

FAQs (FAQs) über asynchrone APIs und serverseitige Rendering React

Was ist der Unterschied zwischen serverseitigem Rendering und clientseitigem Rendering bei React?

serverseitiges Rendering (SSR) und clientseitiges Rendering (CSR) sind zwei verschiedene Möglichkeiten, Webseiten zu rendern. In SSR generiert der Server die vollständige HTML der Seite als Antwort auf die Anforderung und sendet sie dann an den Client. Dies führt zu schnelleren Ladezeiten der Anfangsseite und ist für SEO von Vorteil. Dies kann jedoch dazu führen, dass die Konvertierung von Seiten langsamer ist, da die gesamte Seite mit jeder Anfrage gerendert werden muss. CSR hingegen bedeutet, dass das Rendering im Browser mit JavaScript durchgeführt wird. Dies führt dazu, dass die anfängliche Ladezeit verlangsamt, aber die Seitenumwandlung ist schneller, da nur die erforderlichen Komponenten erneut gerendert werden müssen.

Wie stelle ich eine serverseitige Anforderung in einer von meinem Client gerendeten Reaktionsanwendung?

Um serverseitige Anfragen in einer clientseitigen React-Anwendung zu stellen, können Sie Bibliotheken wie API oder Axios abrufen. Sie können eine Anforderung in der componentDidMount -Lifecycle -Methode oder im useEffect -Haken stellen, wenn Sie die Funktionskomponente verwenden. Die Antwort kann dann auf den Zustand gesetzt und in Ihrer Komponente verwendet werden.

Warum werden meine globalen Variablen zweimal in React ausgeführt?

Dies kann auf die Art und Weise zurückzuführen sein, wie die Aktualisierung des Stapelstatus der Stapel reagiert. Wenn Sie globale Variablen innerhalb einer React -Komponente aktualisieren, kann dies aufgrund der asynchronen Natur von setState zweimal aktualisiert werden. Um dies zu vermeiden, können Sie die Funktionsform von setState verwenden, die sicherstellt, dass das Status -Update auf dem vorherigen Zustand basiert, nicht auf dem aktuellen Zustand.

Wie verwendet man eine asynchrone API in der serverseitigen Reaktion?

Um die asynchrone API in serverseitiger React-React zu verwenden, können Sie die async/await -Syntax im serverseitigen Code verwenden. Auf diese Weise können Sie auf die API -Antwort warten, bevor Sie die Seite rendern. Sie können Bibliotheken wie Axios verwenden, um API -Anfragen zu stellen.

Was sind die Vorteile des serverseitigen Renderings bei React?

serverseitiges Rendering hat viele Vorteile bei React. Es verbessert die Ladezeit der Anfangsseite, was zu einer besseren Benutzererfahrung führen kann. Es verbessert auch die SEO, da Suchmaschinencrawler die serverseitigen Inhalte leichter indexieren können. Darüber hinaus ermöglicht es einen konsistenten Ausgangszustand, da der gleiche Code sowohl auf dem Server als auch auf dem Client ausgeführt wird.

Wie kann man Fehler mit einer asynchronen API in servergerenderten Reaktionen verwenden?

Sie können den try/catch -Block verwenden, um Fehler in einer asynchronen Funktion zu verarbeiten. Auf diese Weise können Sie alle Fehler erfassen, die beim Erstellen von API -Anforderungen auftreten und angemessen umgehen, z. B. durch Wiedergabe von Fehlermeldungen.

Kann ich Hooks in serverseitigem React verwenden?

Ja, Sie können Hooks in servergerenderten React verwenden. Denken Sie jedoch daran, dass Haken nur in Funktionskomponenten verwendet werden können, nicht in Klassenkomponenten. Außerdem werden einige Hooks (z. B. useEffect) auf dem Server nicht ausgeführt. Sie müssen daher sicherstellen, dass Ihr Code diese Situation bearbeiten kann.

Wie verbessert man die Leistung von serverseitigen React-Anwendungen?

Es gibt viele Möglichkeiten, die Leistung von React -Anwendungen für das Serverwiedergabe zu verbessern. Sie können die Code -Segmentierung verwenden, um nur den erforderlichen Code für jede Seite zu laden. Sie können Cache auch verwenden, um die Wiederholung unveränderter Seiten zu vermeiden. Darüber hinaus kann das Optimieren des serverseitigen Codes dazu beitragen, die Leistung zu verbessern.

Wie testet ich meine serverseitige React-Anwendung?

Sie können Testbibliotheken wie Scherz- und React-Testbibliothek verwenden, um Ihre serverseitigen React-Anwendungen zu testen. Diese Bibliotheken ermöglichen es Ihnen, Testkomponenten zu isolieren und sicherzustellen, dass sie korrekt rendern.

Kann ich Server -Rendering mit Next.js verwenden?

Ja, Next.js ist ein Framework für React, das das serverseitige Rendering außerhalb der Box unterstützt. Es bietet eine einfache serverseitige Rendering-API und unterstützt auch die statische Site-Generierung und das Client-Rendering.

Das obige ist der detaillierte Inhalt vonUmgang mit asynchronen APIs in servergerenderten React. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Erklärung dieser Website
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
Neueste Artikel des Autors
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage