Quelle est la pratique générale de définir l'état initial de l'application avec des applications isomorphes? Sans Flux, j'utiliserais simplement quelque chose comme:
var props = { }; // initial state
var html = React.renderToString(MyComponent(props);
Rendez ensuite ce balisage via guidons express et affichez-le via {{{reactMarkup}}
.
Du côté client pour définir l'état initial, je ferais quelque chose comme ceci:
if (typeof window !== 'undefined') {
var props = JSON.parse(document.getElementById('props').innerHTML);
React.render(MyComponent(props), document.getElementById('reactMarkup'));
}
Donc oui, essentiellement, vous définissez l'état deux fois, sur le serveur et le client, cependant React comparera les différences et dans la plupart des cas, cela n'affectera pas les performances en effectuant un nouveau rendu).
Comment ce principe fonctionnerait-il lorsque vous avez des actions et des magasins dans l'architecture Flux? Dans mon composant, je pourrais faire:
getInitialState: function() {
return AppStore.getAppState();
}
Mais maintenant, comment puis-je définir l'état initial dans l'AppStore du serveur? Si j'utilise React.renderToString
Sans propriétés transmises, il appellera AppStore.getAppState()
qui n'aura rien dedans car je ne comprends toujours pas comment définir l'état dans ma boutique sur le serveur ?
Je suis toujours à la recherche d'une solution propre qui n'implique pas l'utilisation d'implémentations Flux tierces comme Fluxible, Fluxxor, Reflux.
Utilisez Redux .
Si vous êtes prêt à travailler avec alt.js vous pouvez y parvenir avec alt.bootstrap
et alt.flush
( documents )
J'utilise le nœud js avec le rendu côté serveur React et alt.js comme implémentation de flux.
Voici à quoi ça ressemble:
var data = {}; // Get the data whatever you want and return it bootstrap ready.
// Reminder - renderToString is synchronised
var app = React.renderToString(
AppFactory(data)
);
// In this point the react rendering was finished so we can flush the data and reset the stores
alt.flush();
Dans mon app.jsx
/**
*
*/
componentWillMount: function () {
// This beauty here is that componentWillMount is run on the server and the client so this is all we need to do. No need for other third-party isomorphic frameworks
alt.bootstrap(
JSON.stringify(this.props, null, 3)
);
}
Jetez un œil à dispatchr et aux bibliothèques associées de yahoo.
La plupart des implémentations de flux ne fonctionnent pas dans node.js car elles utilisent des singleton stockés, des répartiteurs et des actions, et n'ont aucune notion de "nous avons terminé" qui est nécessaire pour savoir quand effectuer un rendu en html et répondre à la demande.
Les bibliothèques de Yahoo comme fetchr et routr contournent cette limitation de nœud en utilisant une forme très pure d'injection de dépendance (pas de fonctions d'analyse pour les noms d'arguments ou quelque chose comme ça).
Au lieu de cela, vous définissez des fonctions api comme celle-ci dans services/todo.js :
create: function (req, resource, params, body, config, callback) {
Et des actions comme celle-ci dans actions/createTodo.js :
module.exports = function (context, payload, done) {
var todoStore = context.getStore(TodoStore);
...
context.dispatch('CREATE_TODO_START', newTodo);
...
context.service.create('todo', newTodo, {}, function (err, todo) {
La dernière ligne appelle indirectement la fonction create dans services/todo.js. Dans ce cas, indirectement, cela peut signifier:
Ce n'est que la pointe de l'iceberg. Il s'agit d'un groupe de modules très sophistiqués qui travaillent ensemble pour résoudre un problème difficile et fournir une API utilisable. L'isomorphisme est intrinsèquement compliqué dans les cas d'utilisation du monde réel. C'est pourquoi de nombreuses implémentations de flux ne prennent pas en charge le rendu côté serveur.
Vous pouvez également envisager de ne pas utiliser de flux. Cela n'a pas de sens pour toutes les applications et gêne souvent. Le plus souvent, vous n'en avez besoin que pour quelques parties de l'application, le cas échéant. Il n'y a pas de balles d'argent dans la programmation!
FakeRainBrigand a raison de dire que le plus gros problème avec Flux côté serveur concerne les singletons. Flummox résout ce problème en n'utilisant pas de singletons et en vous permettant d'encapsuler l'ensemble de votre configuration Flux dans une seule classe réutilisable. Ensuite, vous créez simplement une nouvelle instance à chaque demande. Combiné avec une solution de routage comme React Router, vous pouvez créer des applications entièrement isomorphes.
Même si vous ne voulez pas utiliser Flummox, la source est facile à rechercher et vous pouvez l'utiliser comme un guide pour préparer vous-même quelque chose:
Le problème est que lorsque vous recherchez "Rendu du serveur Flux" , vous vous heurtez immédiatement à cette question et il n'y a aucune mention de Redux , faite par communauté React.js rackt . Vous pouvez trouver bien décrit sur Redux documentation pourquoi le rendu du serveur est important, pourquoi nous devons envoyer l'état initial dans le HTML
au client (c'est là que Flux devient insuffisant) et comment faire alors.