的最大优势之一React.js 应该是 服务器端渲染 .问题是关键函数React.renderComponentToString()
是同步的,这使得无法加载任何异步数据,因为组件层次结构是在服务器上呈现的。
假设我有一个用于评论的通用组件,我可以将其放置在页面上的几乎任何位置。它只有一个属性,某种标识符(例如放置评论的文章的 id),其他所有内容都由组件本身处理(加载、添加、管理评论)。
我真的很喜欢助焊剂 架构因为它让很多事情变得更容易,而且它的存储非常适合在服务器和客户端之间共享状态。一旦我的包含评论的商店被初始化,我就可以将它序列化并将它从服务器发送到客户端,在那里它很容易恢复。
问题是填充我的商店的最佳方式是什么。在过去的几天里,我一直在谷歌上搜索很多,我遇到了一些策略,考虑到 React 的这个特性被“推广”了多少,这些策略似乎都不是很好。
我错过了什么吗?还有另一种方法/解决方案吗?现在我正在考虑采用 react-async/fibers 方式,但我并不完全确定,如第二点所述。
Related discussion on GitHub .显然,没有官方的方法,甚至没有解决方案。也许真正的问题是如何使用 React 组件。喜欢简单的 View 层(几乎是我的建议第一)还是喜欢真正的独立和独立组件?
最佳答案
如果您使用 react-router ,你可以定义一个 willTransitionTo
组件中的方法,通过 Transition
您可以调用的对象 .wait
上。
renderToString 是否同步并不重要,因为回调到 Router.run
直到所有 .wait
才会被调用ed promise 已解决,所以到时候 renderToString
在您可以填充商店的中间件中调用。即使商店是单例,您也可以在同步渲染调用之前临时设置它们的数据,组件会看到它。
中间件示例:
var Router = require('react-router');
var React = require("react");
var url = require("fast-url-parser");
module.exports = function(routes) {
return function(req, res, next) {
var path = url.parse(req.url).pathname;
if (/^\/?api/i.test(path)) {
return next();
}
Router.run(routes, path, function(Handler, state) {
var markup = React.renderToString(<Handler routerState={state} />);
var locals = {markup: markup};
res.render("layouts/main", locals);
});
};
};
routes
对象(描述路由层次结构)与客户端和服务器逐字共享
关于node.js - 异步初始化 React.js 组件的服务器端渲染策略,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25983001/