我做了一个简单的应用程序(在react js中),它有两个列表,您可以向该列表中添加元素。一个是输入元素的列表,另一个是跨度的列表。
添加新元素后,span列表将完美呈现,但输入列表将呈现不同的外观。
这就是我的反应班的样子
var App = React.createClass({ getInitialState: function(){ return { 'app': { 'data': this.props.data, 'data2': this.props.data2 } }; }, onclick: function(){ var dat = this.state.app.data; var val = this.refs.input.getDOMNode().value; dat.splice(0, 0, val); var dat2 = this.state.app.data2; dat2.splice(0, 0, val); this.setState({'app': { 'data': dat, 'data2': dat2 }}); }, renderElement: function(i){ return( <input defaultValue={i} /> ); }, renderElement2: function(i){ return( <span>{i}</span> ); }, render: function(){ var self = this; return( <div> <input type="text" ref="input" placeholder="Enter a value"/> <input type="button" value="Add value" onClick={this.onclick} /> <div className="col2"> {this.state.app.data.map(function(page, i){ return( <div key={i}>{self.renderElement(page)}</div> ); })} </div> <div className="col2"> {this.state.app.data2.map(function(page, i){ return( <div key={i}>{self.renderElement2(page)}</div> ); })} </div> </div> ); } });
这就是应用程序的呈现方式
var data = [1,2,3]; var data2 = [1,2,3]; React.render(<App data={data} data2={data2}/>, document.getElementById("main"));
这是演示
My test case: I add 55 and expect the results to look like this 55 1 2 3 55 1 2 3 But I get 1 2 3 3 55 1 2 3
我在这里缺少基本的东西吗?
首先渲染看起来(大致)如下:
<div> <div key={0}><input defaultValue="1" /></div> <div key={1}><input defaultValue="2" /></div> <div key={2}><input defaultValue="3" /></div> </div> <div> <div key={0}><span>1</span></div> <div key={1}><span>2</span></div> <div key={2}><span>3</span></div> </div>
酷,没有问题。然后,假设我在框中输入了“ foo”,然后单击“添加值”。通过将状态插入到第一项之前来更新状态(注意:splice(0,0,x)是unshift(x)),然后呈现此状态:
<div> <div key={0}><input defaultValue="foo" /></div> <div key={1}><input defaultValue="1" /></div> <div key={2}><input defaultValue="2" /></div> <div key={3}><input defaultValue="3" /></div> </div> <div> <div key={0}><span>foo</span></div> <div key={1}><span>1</span></div> <div key={2}><span>2</span></div> <div key={3}><span>3</span></div> </div>
现在是时候让React接受这两个,并找出发生了什么变化。为此,它会比较组件(此处为div,span或input)和键。
与跨部开始,它会看到所有的代码都相同,但有它以前没有在看到新的密钥 结束 。它也看到了该值div[0] span,div[1] span以及div[2] span都发生了变化。它在末尾插入带有文本3 的 新 元素,并更新其他范围。低效,但有效。
div[0] span
div[1] span
div[2] span
现在,对于输入…它执行大致相同的操作。前三个输入的键和标记是相同的,它告诉每个输入它们正在更新,它们检查它们是否具有值道具,如果没有,则请拒绝执行任何操作。
它看到最后有一个 新 输入。它位于div[3] input,默认值为“ 3”。React插入新的输入,将值设置为3,更新完成。
div[3] input
继续进行时,上述过程相同,并且将继续更新跨度,div span并div input每次都插入新的跨度。
div span
div input
除了defaultValue之外,这里的主要问题是我的键倒置了,除了我认为不应该使用的defaultValue之外!项目是在开始处插入的,因此键应该下降而不是上升。可以通过使用项目的长度并从中减去索引来解决此问题。如果length为4,则关键点将为4,3,2,1。
this.state.app.data.map(function(page, i, items){ return( <div key={items.length - i}>{self.renderElement(page)}</div> ); })
React然后说:“哦,一 开始 有个新项目,我应该在那儿插入一个节点”,每个人都很高兴。结束。