Maison > interface Web > js tutoriel > Traitant des API asynchrones dans la réact rendu du serveur

Traitant des API asynchrones dans la réact rendu du serveur

William Shakespeare
Libérer: 2025-02-16 11:52:10
original
745 Les gens l'ont consulté

Dealing with Asynchronous APIs in Server-rendered React

Résumé des points clés

  • Le rendu côté serveur du code React aide à réduire les temps de chargement et à améliorer la flexibilité du référencement, mais la gestion des API asynchrones peut être difficile en raison de la nécessité de rendre l'application avant de connaître les données requises.
  • Les solutions existantes, telles que Next.js, Redux Connect et React-frontload, ont leurs propres avantages et inconvénients lorsqu'ils traitent des API asynchrones dans le code de réaction rendu du serveur.
  • Les solutions personnalisées peuvent être implémentées en effectuant deux rendus côté serveur: la première fois gère les appels API et les opérations asynchrones, et la deuxième fois utilise les données acquises pour le rendu final de la page.
  • Les solutions de personnalisation nécessitent une manipulation minutieuse des différents états dans le composant, y compris le rendu préfet, post-fetch, pré-rendu et back-end. Cela peut être réalisé via des instructions IF complexes dans le code des composants.
  • Les solutions personnalisées nécessitent également la modification du fichier index.html pour envoyer des données préfectées dans le cadre de la demande de page et l'ajouter à la recherche et à la remplacement. Si vous utilisez des balises de script, vous avez besoin d'un codage de base-64.

Si vous avez déjà fait une page de base de l'application React, il peut avoir de mauvais problèmes de référencement et de performances, en particulier sur des appareils plus lents. Vous pouvez ajouter un rendu de serveur Web traditionnel (généralement à l'aide de NodeJS), mais ce n'est pas un processus facile, surtout lorsqu'il s'agit de API asynchrones.

Les deux principaux avantages du code de rendu côté serveur sont:

  • accélérer la vitesse de chargement
  • Améliorer la flexibilité du référencement

N'oubliez pas que Google attendra que votre JavaScript se charge, donc un contenu simple tel que le contenu de titre changera sans problèmes. (Je ne peux pas dire ce qui se passe avec d'autres moteurs de recherche, cependant, ou à quel point cela est fiable.)

Dans cet article, je vais discuter de la façon d'obtenir des données d'une API asynchrone lors de l'utilisation du code de réaction rendu du serveur. React Code a une structure d'application entière intégrée à JavaScript. Cela signifie que contrairement au mode MVC traditionnel avec les contrôleurs, vous ne savez pas quelles données vous avez besoin avant que l'application ne rende. Avec un cadre comme Create React App, vous pouvez rapidement créer des applications de travail de haute qualité, mais cela vous oblige à gérer le rendu uniquement du côté client. Cela a des problèmes de performances, ainsi que des problèmes de référencement / données, où vous pouvez modifier l'en-tête au besoin.

Question

réagir principalement synchronise le rendu, donc si vous n'avez pas de données, l'écran de chargement sera rendu et en attente de l'arrivée des données. Cela ne fonctionne pas bien du côté serveur parce que vous ne savez pas ce dont vous avez besoin avant de vous rendre, ou vous savez ce dont vous avez besoin, mais vous l'avez rendu.

Afficher cette méthode de rendu standard:

ReactDOM.render(
  <provider> store={store}></provider>
    <browserrouter></browserrouter>
      <app></app>
    >
  >
, document.getElementById('root')
)
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion

Question:

  1. Il s'agit d'un DOM Rendu à la recherche d'éléments radiculaires. Cela n'existe pas sur mon serveur, nous devons donc le séparer.
  2. Nous ne pouvons accéder à rien en dehors de l'élément racine principal. Nous ne pouvons pas définir des balises Facebook, des titres, des descriptions, diverses balises de référencement, et nous ne pouvons pas contrôler le reste du DOM en dehors de l'élément, en particulier les en-têtes.
  3. Nous fournissons certains états, mais le serveur et le client ont des états différents. Nous devons considérer comment gérer cet état (dans ce cas Redux).

donc j'ai utilisé deux bibliothèques ici et elles sont très populaires, donc j'espère qu'elle peut être appliquée aux autres bibliothèques que vous utilisez.

redux: L'état du serveur de stockage et la synchronisation des clients sont un problème de cauchemar. Il est très cher et conduit souvent à des erreurs complexes. Du côté du serveur, idéalement, vous ne voulez rien faire avec Redux, sauf qu'il suffit de faire fonctionner les choses et de rendre correctement. (Vous pouvez toujours l'utiliser comme d'habitude; définissez simplement l'état suffisant pour le faire ressembler à un client.) Si vous voulez l'essayer, consultez les différents guides système distribués comme point de départ.

React-Router: FYI, c'est la version V4, qui est la version installée par défaut, mais elle sera très différente si vous avez un projet existant plus ancien. Vous devez vous assurer de gérer le routage du côté serveur et du côté client et d'utiliser V4 - c'est excellent à cet égard.

Après tout, que se passe-t-il si vous avez besoin de passer un appel de base de données? Cela devient soudainement un gros problème car il est asynchrone et est situé à l'intérieur de votre composant. Bien sûr, ce n'est pas une nouvelle question: le voir dans le référentiel officiel React.

Vous devez rendre pour déterminer les dépendances nécessaires - ces dépendances doivent être déterminées au moment de l'exécution et pour obtenir ces dépendances avant d'être fournies au client.

Solutions existantes

ci-dessous, je reviendrai les solutions actuellement fournies pour ce problème.

suivant.js

Avant de commencer, Suivant.js est idéal pour vous si vous souhaitez que le code réactif est rendu côté serveur ou une application universelle pour votre environnement de production. Il est efficace, concis et a un support Zeit.

Cependant, il est opiniâtre, vous devez utiliser leur chaîne d'outils, et la façon dont ils gèrent le chargement de données asynchrone n'est pas nécessairement si flexible.

Affichez cette copie directe du contenu dans le document de référentiel suivant:

ReactDOM.render(
  <provider> store={store}></provider>
    <browserrouter></browserrouter>
      <app></app>
    >
  >
, document.getElementById('root')
)
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion

getInitialProps est la clé, elle renvoie une promesse qui se résout à un objet rempli d'accessoires et n'est que sur la page. Mieux encore, cela est juste intégré à leur chaîne d'outils: ajoutez-le au travail sans aucun travail!

Alors, comment obtenir des données de base de données? Vous faites un appel API. Tu ne veux pas? Ok, c'est horrible. (D'accord, vous pouvez ajouter du contenu personnalisé, mais vous devez l'implémenter complètement vous-même.) Cependant, si vous y réfléchissez, c'est une pratique très raisonnable et généralement bonne car sinon, votre client sera toujours les mêmes appels API Et la latence sur le serveur est presque négligeable.

Ce que vous pouvez également accéder est limité - presque juste l'objet de demande; Oh, et si vous ne l'avez pas remarqué auparavant, cela ne fonctionne qu'avec des composants de page de niveau supérieur.

redux connect

Redux Connect est un rendu côté serveur très opiniâtre avec une bonne idée, mais ce n'est peut-être pas pour vous si vous n'utilisez pas tous les outils qu'ils décrivent. Ce package a beaucoup de contenu, mais il est très complexe et n'a pas été mis à niveau pour React Router V4. Il existe de nombreux paramètres, mais regardons la partie la plus importante, juste pour apprendre quelques leçons:

ReactDOM.render(
  <provider> store={store}></provider>
    <browserrouter></browserrouter>
      <app></app>
    >
  >
, document.getElementById('root')
)
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion

Les décorateurs ne sont pas standard en JavaScript. Au moment de la rédaction du moment de la rédaction, ils sont dans la phase 2, alors utilisez avec prudence. C'est juste une autre façon d'ajouter des composants d'ordre supérieur. L'idée est simple: la clé est ce qui est passé à vos accessoires, puis vous avez une série de promesses qui analyseront et passeront. Cela a l'air bien. Peut-être qu'une autre option est la suivante:

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>
  }
}
Copier après la connexion
Copier après la connexion

Cela peut être fait avec JavaScript sans trop de problèmes.

react-frontload

Le référentiel React-frontload n'a pas beaucoup de documentation ou d'explications, mais la meilleure compréhension que je puisse obtenir peut provenir des tests (comme celui-ci) et de la lecture du code source. Lorsque quelque chose est monté, il est ajouté à la file d'attente de promesses, et lorsque la file d'attente est analysée, elle est servie. Ce qu'il fait est très bien, bien qu'il soit difficile de recommander quelque chose qui n'est pas bien documenté, entretenu ou utilisé:

// 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>
    )
  }
}
Copier après la connexion
Copier après la connexion

à la recherche de meilleures solutions

Aucune des solutions ci-dessus ne correspond vraiment à mes attentes pour la flexibilité et la simplicité de la bibliothèque, donc je vais maintenant présenter ma propre implémentation. L'objectif n'est pas d'écrire des packages, mais de vous donner une idée de la façon d'écrire vos propres packages en fonction de votre cas d'utilisation.

Le référentiel de cet exemple de solution est situé ici.

théorie

L'idée derrière elle est relativement simple, bien qu'elle finisse par produire beaucoup de code. Il s'agit de décrire les idées dont nous discutons.

Le serveur doit rendre le code réact deux fois, et nous n'utiliserons que renderToString pour cela. Nous voulons garder le contexte entre les premier et deuxième rendus. Dans notre premier rendu, nous avons essayé d'éliminer tous les appels, promesses et opérations asynchrones. Dans notre deuxième rendu, nous voulons prendre toutes les données que nous obtenons et la remettre dans notre contexte, en rendant notre page de travail pour la distribution. Cela signifie également que le code d'application doit effectuer des actions en fonction du contexte (ou non des opérations d'exécution), par exemple s'il est sur le serveur ou sur le navigateur, et dans les deux cas si les données sont récupérées.

De plus, nous pouvons le personnaliser au besoin. Dans ce cas, nous modifions le code d'état et l'en-tête en fonction du contexte.

First rendu

Dans votre code, vous devez savoir si vous travaillez sur le serveur ou sur le navigateur, idéalement, vous voulez avoir un contrôle complexe dessus. Avec React Router, vous pouvez obtenir un accessoire de contexte statique, ce qui est génial, nous allons donc l'utiliser. Actuellement, nous ajoutons simplement un objet de données et demandons des données, comme nous l'avons appris de Next.js. Nos API varient entre le serveur et le client, vous devez donc fournir une API de serveur qui est préférable d'avoir une interface similaire à votre API client:

ReactDOM.render(
  <provider> store={store}></provider>
    <browserrouter></browserrouter>
      <app></app>
    >
  >
, document.getElementById('root')
)
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion

Deuxième rendu

Après le premier rendu, nous obtiendrons ces promesses en attente et attendrons que ces promesses se terminent, puis renforcent, mettant à jour le contexte:

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>
  }
}
Copier après la connexion
Copier après la connexion

App

Passez rapidement de notre serveur vers le code d'application: Dans n'importe lequel de nos composants avec des connexions de routeur, nous pouvons l'obtenir maintenant:

// 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>
    )
  }
}
Copier après la connexion
Copier après la connexion

wow, il y a beaucoup de code compliqué. À ce stade, vous voudrez peut-être adopter une approche plus relayée où vous séparez le code de récupération des données dans un autre composant.

Ce composant se compose de composants que vous connaissez peut-être - des étapes de rendu et componentWillMount. Les instructions IF en quatre étapes gèrent différents états: rendu post-fetch, post-rendu et back-end. Nous ajoutons également les données à l'en-tête une fois qu'elle est chargée.

Enfin, il y a une autre étape pour obtenir les données. Idéalement, votre API et votre base de données ont la même API, ce qui rend l'exécution la même. Vous voudrez peut-être les mettre dans des actions dans Thunk ou Saga pour les rendre plus évolutives.

Affichez l'article "REACTER REACT SERVER" et le rendu du serveur React Reactory pour plus d'informations. N'oubliez pas que vous devez toujours gérer l'état où les données ne sont pas chargées! Vous ne ferez un rendu côté serveur que lorsque le premier chargement, vous afficherez donc l'écran de chargement sur les pages suivantes.

modifier index.html pour ajouter des données

Nous devons envoyer des données préfabriquées dans le cadre de la demande de page, nous ajouterons donc une balise de script:

@asyncConnect([{
  lunch: ({ params, helpers }) => Promise.resolve({ id: 1, name: 'Borsch' })
}])
Copier après la connexion

Service

Ensuite, nous devons l'ajouter à notre recherche et à notre remplacement. Cependant, HTML utilise un chercheur de balises de script très basique, donc si vous avez des balises de script, vous avez besoin de la base-64 encodant. Aussi, n'oubliez pas nos étiquettes de tête!

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

return frontloadServerRender(() => (
  render(<app></app>)
)).then((serverRenderedMarkup) => {
  console.log(serverRenderedMarkup)
})
Copier après la connexion

Nous gérons également les modifications du code d'état - par exemple, pour 404 - donc si vous avez une page 404, vous pouvez le faire:

const context = {data: {}, head: [], req, api}
const store = configureStore()
renderToString(
  <provider> store={store}></provider>
    <staticrouter> location={req.url} context={context}>
      <app></app>
    >
  >
)
Copier après la connexion

Résumé

Si vous n'êtes pas sûr de ce que vous faites, utilisez simplement Next.js. Il est conçu pour le rendu côté serveur et les applications universelles, ou si vous voulez que la flexibilité fasse tout manuellement, vous pouvez le faire comme vous le souhaitez. Un exemple peut vous inclure de faire des données en train de récupérer dans un composant enfant plutôt qu'au niveau de la page.

J'espère que cet article pourra vous aider à démarrer! N'oubliez pas de consulter le référentiel GitHub pour une implémentation viable.

FAQS (FAQ) sur les API asynchrones et le rendu de côté du serveur React

Quelle est la différence entre le rendu côté serveur et le rendu côté client dans React?

Le rendu côté serveur (SSR) et le rendu côté client (CSR) sont deux façons différentes de rendre les pages Web. Dans SSR, le serveur génère le HTML complet de la page en réponse à la demande, puis l'envoie au client. Il en résulte des temps de chargement initiaux plus rapides et est bénéfique pour le référencement. Cependant, cela peut faire en sorte que la conversion de la page soit plus lente, car la page entière doit être rendue à chaque demande. CSR, en revanche, signifie que le rendu se fait dans le navigateur à l'aide de JavaScript. Cela fait ralentir le temps de chargement de la page initiale, mais la conversion de la page est plus rapide car seuls les composants nécessaires doivent être renvoyés.

Comment faire une demande côté serveur dans une application React rendue par mon client?

Pour faire des demandes côté serveur dans une application REACT renvoyée côté client, vous pouvez utiliser des bibliothèques telles que API Fetch ou Axios. Vous pouvez faire une demande dans la méthode du cycle de vie componentDidMount ou dans le crochet useEffect lors de l'utilisation du composant de fonction. La réponse peut ensuite être définie sur l'état et utilisé dans votre composant.

Pourquoi mes variables globales sont-elles exécutées deux fois en réaction?

Cela peut être dû à la façon dont les mises à jour de l'état de lots réagissent. Si vous mettez à jour les variables globales dans un composant React, il peut être mis à jour deux fois en raison de la nature asynchrone de setState. Pour éviter cela, vous pouvez utiliser la forme de fonction de setState, qui garantit que la mise à jour de l'état est basée sur l'état précédent, et non sur l'état actuel.

Comment utiliser une API asynchrone dans la réaction rendue côté serveur?

Pour utiliser l'API asynchrone dans la réaction rendue côté serveur, vous pouvez utiliser la syntaxe async/await dans le code côté serveur. Cela vous permet d'attendre la réponse de l'API avant de rendre la page. Vous pouvez utiliser des bibliothèques telles que Axios pour faire des demandes d'API.

Quels sont les avantages du rendu côté serveur dans React?

Le rendu côté serveur présente de nombreux avantages en réaction. Il améliore le temps de chargement des pages initial, ce qui peut conduire à une meilleure expérience utilisateur. Il améliore également le référencement car les robots des moteurs de recherche peuvent indexer plus facilement le contenu rendu côté serveur. De plus, il permet un état initial plus cohérent, car le même code s'exécute sur le serveur et le client.

Comment gérer les erreurs lors de l'utilisation d'une API asynchrone dans REACT rendu du serveur?

Vous pouvez utiliser le bloc try/catch pour gérer les erreurs dans une fonction asynchrone. Cela vous permet de capturer toutes les erreurs qui se produisent lors de la création de demandes d'API et de les gérer de manière appropriée, par exemple en rendant les messages d'erreur.

Puis-je utiliser des crochets dans React Rended Side Rendered?

Oui, vous pouvez utiliser des crochets dans React rendu du serveur. Cependant, n'oubliez pas que les crochets ne peuvent être utilisés que dans les composants de la fonction, pas dans les composants de la classe. De plus, certains crochets (par exemple useEffect) ne s'exécuteront pas sur le serveur, vous devez donc vous assurer que votre code peut gérer cette situation.

Comment améliorer les performances des applications REATS rendues côté serveur?

Il existe de nombreuses façons d'améliorer les performances des applications React pour le rendu des serveurs. Vous pouvez utiliser la segmentation du code pour charger uniquement le code nécessaire pour chaque page. Vous pouvez également utiliser le cache pour éviter la rediffusion des pages inchangées. De plus, l'optimisation du code côté serveur peut aider à améliorer les performances.

Comment tester mon application REACT rendue côté serveur?

Vous pouvez utiliser des bibliothèques de tests telles que la bibliothèque de tests et de réaction pour tester vos applications React rendues côté serveur. Ces bibliothèques vous permettent d'isoler les composants de test et de vous assurer qu'ils rendent correctement.

Puis-je utiliser le rendu de serveur avec next.js?

Oui, Next.js est un framework pour React qui prend en charge le rendu de la boîte. Il fournit une simple API de rendu côté serveur et prend également en charge la génération de sites statique et le rendu client.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Derniers articles par auteur
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal