43

使用同构应用程序设置应用程序初始状态的一般做法是什么?如果没有 Flux,我会简单地使用类似的东西:

var props = { }; // initial state
var html = React.renderToString(MyComponent(props);

然后通过express-handlebars渲染该标记并通过{{{reactMarkup}}.

在客户端设置初始状态我会做这样的事情:

if (typeof window !== 'undefined') {
    var props = JSON.parse(document.getElementById('props').innerHTML);
    React.render(MyComponent(props), document.getElementById('reactMarkup'));
}

所以是的,基本上你在服务器和客户端设置了两次状态,但是 React 会比较差异,并且在大多数情况下,它不会通过重新渲染来影响性能。


当你在 Flux 架构中有操作和存储时,这个原则将如何工作?在我的组件中,我可以这样做:

getInitialState: function() {
  return AppStore.getAppState();
}

但是现在如何从服务器设置AppStore中的初始状态?如果我使用React.renderToString没有传递的属性,它将调用AppStore.getAppState()其中没有任何内容,因为我仍然不明白如何在服务器上的商店中设置状态?

2015 年 2 月 5 日更新

我仍在寻找一个干净的解决方案,它不涉及使用第三方 Flux 实现,如Fluxible、Fluxxor、Reflux

2016 年 8 月 19 日更新

使用Redux

4

4 回答 4

14

看看dispatchr和 yahoo 的相关库。

大多数通量实现在 node.js 中不起作用,因为它们使用单​​例存储、调度程序和操作,并且没有“我们完成”的概念,这需要知道何时呈现到 html 并响应请求。

像 fetchr 和 router 这样的 Yahoo 库通过使用非常纯粹的依赖注入形式(没有解析参数名称或类似的函数)来绕过节点的这种限制。

相反,您可以在services/todo.js中定义这样的 api 函数:

create: function (req, resource, params, body, config, callback) {

在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) {

最后一行间接调用了 services/todo.js 中的 create 函数。在这种情况下,间接可以意味着:

  • 在服务器上:
    • 当您在服务器上时,fetchr 会填写额外的参数
    • 然后它会调用你的回调
  • 在客户端:
    • fetchr 客户端发出一个 http 请求
    • 服务器上的 fetchr 拦截它
    • 它使用正确的参数调用服务函数
    • 它将响应发送回客户端 fetchr
    • 客户端 fetchr 处理调用你的回调

这只是冰山一角。这是一组非常复杂的模块,它们协同工作以解决棘手的问题并提供可用的 api。在现实世界的用例中,同构本质上是复杂的。这就是为什么许多通量实现不支持服务器端渲染的原因。

您可能还想研究不使用助焊剂。它对所有应用程序都没有意义,而且经常会妨碍您。大多数情况下,如果有的话,您只需要它用于应用程序的几个部分。编程没有灵丹妙药!

于 2014-12-06T22:21:17.497 回答
3

FakeRainBrigand 是正确的,服务器端 Flux 的最大问题是单例。Flummox 通过不使用单例解决了这个问题,使您能够将整个 Flux 设置封装到一个可重用的单个类中。然后,您只需在每个请求上创建一个新实例。结合 React Router 之类的路由解决方案,您可以制作完全同构的应用程序。

即使您不想使用 Flummox,源代码也很容易理解,您可以将其用作自己的指南:

https://github.com/acdlite/flummox

于 2015-02-05T21:00:47.173 回答
1

如果你愿意使用alt.js,你可以使用alt.bootstrapand alt.flush( docs )

我正在使用带有反应服务器端渲染的节点 js 和 alt.js 作为我的通量实现。

这是它的外观:

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();

在我的 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)
    );

}
于 2015-08-29T11:47:15.450 回答
0

问题是,当您搜索“Flux 服务器渲染”时,您会立即遇到这个问题,并且没有提到Redux,由React.js 社区 rackt 制作。你可以在 Redux 的文档中找到很好的描述为什么服务器渲染很重要,为什么我们需要在HTML客户端中发送初始状态(这是 Flux 变得不足的地方)以及如何这样做。

于 2015-11-17T23:36:03.210 回答