反应没有在客户端代码插入跨度?

首先,我是新的反应,最近我通过推文直播stream本教程 。

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

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

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

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

为什么客户端没有在一个范围内包装列表项内容,因为反应是应该做的。 如果重要的话,文本被插入为prop {this.props.text}

我可以提供一些代码,但是我不确定会有什么帮助,这些都是非常基本的。 tweet item 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通过脚本标记作为其初始状态发送(加载旧的tweets) <script id="initial-state" type="application/json">{{{state}}}</script>因此,从这里开始,我通过去除传递状态立即得到它,使链接出现,但这可能导致缺乏持久性。 我需要testing一下。 处理这个initial-state的最好方法是什么? 在客户端更新它,或完全删除它?

任何帮助表示赞赏!

我相信你想要做的是这个

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

如果你手动包装在一个跨度,反应显然不会包装在一个额外的跨度,它将永远在那里。

一般来说,我认为它是一个更好的做法,以包装具有跨度“自动”跨度的任何东西。 这样你的代码中就没有什么“神奇”的事情发生,每次你都可以得到特定的结果

请记住,如果您正在进行更改,则必须重新编译源代码以查看更改生效,也就是运行构build过程gulp / grunt / duo …等等。

编辑:

你的更新后,它看起来像你忘了添加该脚本标签到您的HTML。 如果你看这里的HTML包括该脚本标签(search<script id="initial-state" )。 它看起来像你需要包括在您的网页上。 如果没有这样的节点,反应不知道该怎么做,所以它重绘所有的东西到DOM。