ReactJS能否根据服务器端渲染的DOM初始化其状态?

3
我喜欢在React中使用同构JavaScript的容易程度。但唯一让我感到困扰的是,浏览器需要下载两次数据。首先在DOM标记中下载,然后以JSON格式再次下载以在运行时初始化状态。既然所有数据都已经在DOM中,那么React不应该能够仅基于DOM重新生成吗?

screenshot of react component rendered server-side screenshot of the data duplicated in JSON format

我尝试使用自定义绑定程序在KnockoutJS中进行渐进增强实验progressive enhancement in KnockoutJS。我希望能够用类似的方式在React中实现相似的效果。

//Custom binding to load the values into the view model from the DOM
ko.bindingHandlers.PE = {
    init: function(element, valueAccessor, allBindings) {
        var bindings = allBindings();
        if (typeof bindings.text === 'function') {
            bindings.text($(element).text());
        }
    }
};

更新

在React中放置读取DOM值的逻辑似乎不是惯用方法。但是,没有什么能阻止您编写一些JavaScript代码以自己收集值!鉴于以上示例,您可以执行以下操作。

var comments = $('.media').map(function() {
  return {
    Author: $(this).find('.media-object').attr('src'),
    Text: $(this).find('.media-body').text()
  };
});

然后使用它来在客户端初始化React组件。我对此感到满意。

2个回答

2

在React中,渲染是一种单向转换。它不会在DOM中存储足够的信息来重构创建DOM的数据结构。 data-react-id 属性用于React的差异算法,但不用于存储有关用户数据的信息。

从您的示例中(这里的data-react-id是任意的,我手写了它们):

var Comment = React.createClass({
  render: function() {
    return (
      <div className="comment">
        <h3 className="commentAuthor">{this.props.comment.Author}</h3>
        {this.props.comment.Text}
      </div>
    );
  }
});

React.render(
  <Comment comment={{"Author": "Shellie", "Text": "semper, dui lectus"}} />,
  ...
);

...

<!-- Output -->
<div class="comment" data-react-id=".x.0">
  <h3 class="commentAuthor" data-react-id=".x.0.0">Shellie</h3>
  <span data-react-id=".x.0.1">semper, dui lectus</span>
</div>

DOM中没有关于字符串“Shellie”来自哪里或“semper,dui lectus”来自哪里的信息。该示例产生相同的输出:

var Comment = React.createClass({
  render: function() {
    return (
      <div className="comment">
        <h3 className="commentAuthor">Shellie</h3>
        semper, dui lectus
      </div>
    );
  }
});

React.render(
  <Comment />,
  ...
);

...

<!-- Output -->
<div class="comment" data-react-id=".x.0">
  <h3 class="commentAuthor" data-react-id=".x.0.0">Shellie</h3>
  <span data-react-id=".x.0.1">semper, dui lectus</span>
</div>

0

你真正想做的是通过脚本标签将服务器端渲染使用的数据存储在JavaScript变量中,然后从客户端对象初始化你的React,而不是从服务器端。


对的,上面的截图就是这样做的,并且它有效。但是我认为如果有一种注释的方式让React能够使用DOM中的值来初始化其运行时模型,然后随时间更新附加数据,那将会非常有用。 - SavoryBytes
是的,正如其他评论者所说,这违反了单向数据流的思想。很抱歉,我真的没有更好的方法来做到这一点,应该更仔细地阅读。 - user3807087

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接