web-dev-qa-db-fra.com

La fenêtre .__ INITIAL_STATE__ est-elle toujours le moyen préféré de transmettre l'état initial au client dans React Universal apps?

Je lis actuellement n livre à propos de React et les applications universelles dans lesquelles l'auteur affirme que la meilleure pratique est de passer l'état initial du serveur au client:

server.js

import React from 'react';
import {renderToStaticMarkup} from 'react-dom/server';
import Myapp from '../MyApp';
import api from '../services';

function renderPage(html, initialData) {
    return `
        <html>
            <body>
                ${html}
            </body>
            <script>
                window.__INITIAL_STATE__ = ${JSON.stringify(initialData)};
            </script>
            <script src="bundle.js"></script>
        </html>
    `;
}

export default function(request, reply) {
    const initialData = api.getData();
    const html = renderToStaticMarkup(<MyApp />);
    reply(renderPage(html, initialData);
}

Et puis, dans le client, vous lisez les données comme ceci:

bundle.js

const initialData = window.__INITIAL_STATE__ || {};
const mountNode = document.getElementById('root');
ReactDOM.render(<MyApp />, mountNode);

D'après ce que je comprends, l'état initial est d'abord converti en chaîne, puis attaché en tant qu'objet global littéral à l'objet fenêtre.

Cette solution me semble très approximative. Le livre a été publié à la mi-2016. L'utilisation de window.__INITIAL_STATE__ encore la façon de procéder ou existe-t-il de meilleures solutions?

Par exemple, je pourrais imaginer qu'il serait possible d'offrir l'état initial dans un appel de micro-service séparé qui pourrait alors être mieux mis en cache que si les données étaient intégrées directement dans le document car les données d'état initial doivent être transférées tous les heure d'actualisation de la page, même si les données n'ont pas changé.

14
Timo

Réponse simple: oui.

Mais je ne sais pas pourquoi personne n'a souligné que vous avez une vulnérabilité XSS très courante en utilisant JSON.stringify(initialData) ce que vous voulez faire à la place est de:

import serialize from 'serialize-javascript';

 window.__INITIAL_STATE__ = ${serialize(initialData)};
11
user3376065

HTTP fonctionne en mettant en cache les réponses, dans votre cas, si l'état initial sera toujours le même, vous pouvez également le mettre en cache côté serveur et l'afficher dans la page, cela fonctionnera plus rapidement, car react aura immédiatement accès à cette valeur donc il ne faudra pas attendre. Vous pouvez également forcer le navigateur à mettre en cache la page, de sorte que la réponse de la page sera la même, l'état initial ne changeant pas.

Avec la demande d'appel supplémentaire, vous comptez sur le navigateur pour mettre en cache cet appel, mais vous devrez créer une étape supplémentaire, faire réagir à nouveau le rendu lorsque les informations arrivent ou bloquer réagir au rendu jusqu'à ce que les informations soient prêtes.

Je vais donc aller avec le numéro 1, vous donne plus de flexibilité et un autre Nice d'avoir, comme le rendu du serveur, qui peut être facilement réalisé après avoir chargé l'état dans le serveur.

0
Franco Risso