【问题标题】:React not inserting span in client code?反应不在客户端代码中插入跨度?
【发布时间】:2015-10-25 23:54:36
【问题描述】:

首先,我是新手,最近我处理了这个tutorial on tweet live stream

长话短说,我想在每条推文后面添加一个链接。为此,我只需将道具添加到包含 url 和用户名的推文项目。

当我查看该网站时,链接就在那里,然后它们立即消失。

在控制台中,我收到警告:“React 尝试在容器中重用标记,但校验和无效。这通常意味着您正在使用服务器渲染,而服务器上生成的标记不是客户端的期待。React 注入了新的标记来补偿哪些有效,但是您已经失去了服务器渲染的许多好处。相反,要弄清楚为什么在客户端或服务器上生成的标记是不同的”

这里出错的原因是服务器将列表项渲染为<li react id...> <span react-id ...>,而客户端渲染为<li react-id ...> Text here with no span tag </li>

为什么客户端不将列表项内容包装在一个跨度中,就像 react 应该做的那样。如果重要,文本将作为道具 {this.props.text} 插入。

我可以提供一些代码,但我不确定什么会有所帮助,这都是非常基本的。推文项 render() 返回如下:

return (
  <li className="list-group-item">{this.props.text}<a href={this.props.url}>{this.props.user}</a></li>
);

服务端渲染如下(nodejs/express):

  var markup = React.renderToString(Tweets({ data: tweet_list.reverse() }));
  console.log(markup);
  res.render('index', {
    markup: markup,
    state: JSON.stringify(tweet_list)
  });    

编辑

摘自服务​​器标记(一个列表项):

<li class="list-group-item" data-reactid=".21kkf2bdurk.1.$651">
  <span data-reactid=".21kkf2bdurk.1.$651.0">RT @JeffLindner1: Law enforcement has reopened all mainlanes of I-10 at White Oak Bayou except 1 west bound lane. # houwx</span>
  <a href="https://twitter.com/KPRC2/status/658219790318698496" data-reactid=".21kkf2bdurk.1.$651.1">KPRC2</a>
</li>

摘自客户端/查看源代码:

<div id='view'><div data-reactid=".21kkf2bdurk" data-react-checksum="1889651106">
  <h1 data-reactid=".21kkf2bdurk.0">Tweets</h1>
  <ul class="tweets list-group" data-reactid=".21kkf2bdurk.1">
    <li class="list-group-item" data-reactid=".21kkf2bdurk.1.$0">
      <span data-reactid=".21kkf2bdurk.1.$0.0">RT @EdwardEgrosFox4: Cole Beasley gets comforted by Jason Witten after botching the punt return. https://t.co/jF9MxRN9BV</span>
      <a href="https://twitter.com/FOX4/status/658431262240059392" data-reactid=".21kkf2bdurk.1.$0.1">FOX4</a>
    </li>

所以跨度就在那里。然而警告的结尾是:

(client) ".21kkf2bdurk.1.$0">RT @EdwardEgrosFox4:
(server) ".21kkf2bdurk.1.$0"><span data-reactid="

编辑 2

所以,当我检查输出 html 时,唯一的区别是服务器呈现的 html 作为其初始状态(加载旧推文)通过脚本标签发送 &lt;script id="initial-state" type="application/json"&gt;{{{state}}}&lt;/script&gt; 因此,从这里开始,我立即通过删除传递的状态使其工作,使链接出现,但这可能会导致缺乏持久性。我需要测试才能确定。处理这个initial-state 的最佳方法是什么?在客户端更新它,还是完全删除它?

感谢任何帮助!

【问题讨论】:

  • 在 sn-ps 上,您的数据 reactid 看起来不同.. 这可能使其将所有内容重绘到 Dom。查看我发布的关于打印前后准确输出的评论,并确保它们首先相同
  • 嘿约翰,我部分弄清楚出了什么问题,如果你能看一下,我会更新我的帖子
  • 好的,我编辑了一个潜在的解决方案。我相信您需要添加该脚本标签。

标签: javascript node.js reactjs


【解决方案1】:

我相信你想做的就是这个

return (
    <li className="list-group-item">
        <span>{this.props.text}</span>
        <a href={this.props.url}>{this.props.user}</a>
    </li>
);

如果你手动将它包装在一个 span 中,react 显然不会将它包装在一个额外的 span 中,它会一直存在。

一般来说,我认为将任何将具有“自动”跨度的内容与特定的跨度进行包装是一种更好的做法。这样,您的代码中就不会“神奇地”发生任何事情,并且您每次都可以获得特定的期望结果

记住如果您要进行更改,则必须重新编译源代码才能看到更改生效,也就是运行您的构建过程 gulp / grunt / duo ... 等等.

编辑:

在您更新后,您似乎忘记将脚本标签添加到您的 html 中。如果您查看 Here,则 html 包含该脚本标记(搜索 &lt;script id="initial-state")。看起来您需要将其包含在您的页面上。当缺少这样的节点时,react 不知道该怎么做,因此它将所有内容重绘到 DOM。

【讨论】:

  • 嗯,这太奇怪了..我以为这会解决它!但它没有。无论出于何种原因,控制台都坚持认为客户端 HTML 仍然缺少跨度。它显然被剥夺了。警告摘录:“(client) =".6pntflc3y8.1.$0">tweet_text_here.... (server) =".6pntflc3y8.1.$0">
  • 您能否在服务器端(即console.log(markup);)发布 sn-ps 以及客户端上的 html 标记(检查元素)
  • 当然,我会把它添加到主帖
  • @TrésDuBiel 也看看这个错误报告。那里有一些有用的提示可以比较之前和之后的html,看看是否/有什么不同github.com/yahoo/flux-examples/issues/69
  • John,出于某种原因,运行 gulp react 解决了所有问题。如果您可以在答案中添加关于原因的评论,我将其标记为正确。感谢您的所有帮助
猜你喜欢
  • 2016-08-20
  • 1970-01-01
  • 2014-03-07
  • 1970-01-01
  • 2019-11-21
  • 1970-01-01
  • 1970-01-01
  • 2019-06-01
  • 1970-01-01
相关资源
最近更新 更多