【发布时间】:2015-02-14 03:38:44
【问题描述】:
我的问题
我正在React 中构建一个同构应用程序,它首先在服务器端渲染组件,然后利用 React 的智能重新渲染浏览器端。
我遇到了一种情况,在 React 能够首先呈现浏览器端之前,DOM 可能与 React 组件的状态不同步。当用户的互联网连接速度较慢时,可能会发生这种情况,并且 react.js 文件需要一段时间才能下载(这也是我构建同构应用程序的原因)
示例
这是我整理的一个例子来展示这种情况:http://jsfiddle.net/jesstelford/z4o44esb
- 运行此示例
- 切换复选框
- 点击“渲染反应”
- 当前 React 状态在控制台中输出
- 请注意,它仍然设置为 { done: false } 这是不正确的
var TodoItem = React.createClass({
// ...
render: function() {
return (
<label>
<input type="checkbox" defaultChecked={this.state.done} onChange={this.onChange} />
{this.props.name}
</label>
);
}
});
// User toggles checkbox ON here, before React is rendered browser-side
// render using React browser-side
var renderedComponent = React.render(component, document.getElementById('content'));
// Incorrectly outputs { done: false }
console.log('React state:', renderedComponent.state);
可能的(一半)解决方案
我找到了一种使用React refs的可能解决方案:http://jsfiddle.net/jesstelford/z4o44esb/2
var TodoItem = React.createClass({
// ...
syncStateFromDOM: function() {
this.setDone(this.refs.done.getDOMNode().checked);
},
render: function() {
return (
<label>
<input ref="done" type="checkbox" defaultChecked={this.state.done} onChange={this.onChange} />
{this.props.name}
</label>
);
}
});
// User toggles checkbox ON here, before React is rendered browser-side
// render using React browser-side
var renderedComponent = React.render(component, document.getElementById('content'));
// Sync state from the DOM
renderedComponent.syncStateFromDOM()
// Correctly outputs { done: true }
console.log('React state:', renderedComponent.state);
这种方法的缺点是:
- 状态在在渲染 DOM 之后同步
- 需要组件本身外部的额外代码才能在首次渲染时同步
我的问题
在服务器端预渲染 React 组件时,有没有办法在 React 组件渲染浏览器端之前将 DOM 状态同步到该 React 组件,因为在浏览器端加载 React 之前用户已经操作了 DOM ?
谢谢!
【问题讨论】:
-
您能否详细说明“用户更改了服务器端的状态”是什么意思?
-
我没有在问题的任何地方这么说 - 还有其他短语可以为您澄清吗?
-
啊,没有意识到你延迟渲染 React 的时间比 document#ready 长。很抱歉。
标签: reactjs isomorphic-javascript