React + Flux和服务器端渲染? (同构反应+通量)

时间:2014-12-06 21:41:05

标签: javascript express reactjs flux isomorphic-javascript

使用同构应用程序设置应用程序的初始状态的一般做法是什么?没有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 个答案:

答案 0 :(得分:14)

查看dispatchr和雅虎相关的图书馆。

大多数助焊器实施都不在node.js中工作,因为它们使用单​​例存储,调度程序和操作,并且没有"我们已经完成的概念"需要知道何时呈现为html并响应请求。

像fetchr和routr这样的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。在现实世界的用例中,同构性本质上是复杂的。这就是为什么许多通量实现不支持服务器端渲染的原因。

您可能还想研究不使用助焊剂。它对所有应用程序都没有意义,而且往往只是妨碍了。大多数情况下,如果有的话,你只需要它的几个部分。编程中没有银子弹!

答案 1 :(得分:3)

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

即使您不想使用Flummox,也很容易理解来源,您可以将其用作指导自己鞭打的东西:

https://github.com/acdlite/flummox

答案 2 :(得分:1)

如果您愿意使用alt.js,则可以使用alt.bootstrapalt.flushdocs

来实现这一目标

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

它的外观如下:

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

}

答案 3 :(得分:0)

问题是,当您搜索" Flux服务器渲染" 时,您会立即碰到这个问题而且没有提到Redux,通过 React.js社区 rackt。您可以在Redux的documentation上找到很好的描述,为什么服务器渲染很重要,为什么我们需要在HTML内向客户端发送初始状态(这是Flux变得不足的地方)以及如何做如此。