我制作了一个简单的应用程序(在 React js 中),它有两个列表,您可以向该列表添加元素。一个是输入元素列表,另一个是跨度列表。
添加新元素后,跨度列表呈现完美,但输入列表呈现不同。
这就是我的 react 类的样子
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"));
这是DEMO
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 或此处的输入)和键。
从span部分开始,它看到所有标签都是相同的,但是在末尾有一个以前没有见过的新键。它还发现 div[0] span
、div[1] span
和 div[2] span
的值都已更改。它插入末尾带有文本 3 的 new 元素,并更新其他跨度。效率低下,但有效。
现在对于输入...它的作用大致相同。前三个输入的键和标签是相同的,它告诉每个输入它们正在更新,它们检查它们是否有 value 属性,如果没有,请拒绝执行任何操作。
它看到末尾有一个新输入。它位于 div[3] input
处,默认值为“3”。 React 插入新的输入,将值设置为 3,更新完成。
当您继续时,上述过程是相同的,并且它会继续更新范围,并每次插入新的 div span
和 div input
。
这里的主要问题,除了我认为不应该使用的 defaultValue 之外,是按键颠倒了!项目是在开头插入的,因此键应该下降,而不是上升。这可以通过使用项目的长度并从中减去索引来解决。如果长度为 4,则 key 将为 4, 3, 2, 1。
this.state.app.data.map(function(page, i, items){
return(
<div key={items.length - i}>{self.renderElement(page)}</div>
);
})
React 然后说“哦,开头有一个新项目,我应该在那里插入一个节点”,然后每个人都很高兴。结束。
关于reactjs - react js : Input element renders differently compared to other elements,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28258517/