我正在渲染一个字符串数组作为文本输入。渲染时,我渲染一个额外的输入,它会更新一个超过数组末尾的索引。问题是在输入第一个字符后,首次渲染新输入时,当前输入失去焦点。 (Fiddle)
这些项目有一个关键道具,包括超出阵列末尾的一个额外项目。我应该提交错误报告,还是我在这里缺少关于表单输入如何工作的东西?
let MiniList = React.createClass({
getInitialState() {
return {
items: []
};
},
update( index, value ) {
let items = this.state.items;
items[ index ] = value;
this.setState({ items: items });
},
renderItem( value, index ) {
return (
<div key={ index }>
{ index }
<input type="text"
value={ value }
onChange={ event => this.update( index, event.target.value )}/>
</div>
);
},
render() {
return (
<div>
{ this.state.items.map( this.renderItem )}
{ this.renderItem( null, this.state.items.length )}
</div>
);
}
});
React.render( <MiniList />, document.body );
答案 0 :(得分:3)
<div>
{ this.state.items.map( this.renderItem )}
{ this.renderItem( null, this.state.items.length )}
</div>
编译到
React.createElement("div", null,
this.state.items.map( this.renderItem ),
this.renderItem( null, this.state.items.length )
)
this.state.items.map( this.renderItem )
中每个元素的键将以子列表中的数组索引作为前缀(在您的情况下为0
)。这使得this.state.items.map( this.renderItem )
中的任何元素与this.renderItem( null, this.state.items.length )
返回的元素之间的协调变得不可能,因为它们不会共享相同的密钥。因此,当您向this.state.items
添加新项目时,将卸载最后一个输入并在其位置安装新输入,这可以解释失去焦点。
要解决此问题,请确保所有商品元素都在同一个数组中。
<div>
{
this.state.items
.map( this.renderItem )
.concat( [this.renderItem( null, this.state.items.length )] )
}
</div>
或只是
<div>
{ this.state.items.concat([null]).map( this.renderItem ) }
</div>