假设我在React组件中有下一段代码
removeItem = (item) => {
this.items.remove(item) // this.items -> mobx array
}
renderItem = (item, index) => {
var _item = undefined
switch (item.type) {
case "header":
_item = <Header key={item.id} onRemove={() => this.removeItem(item)} />
// a few more cases
// note that item.id is unique and static
}
// return _item -> works fine
return [
_item,
this.state.suggested
? <Placeholder key={-item.id} />
: null
]
}
render() {
return (
<div>
{this.items.map((item, i) => renderItem(item))}
</div>
)
}
还假设在每个项目中我都有一个触发onRemove处理程序的按钮。每个组件都有textarea,用户可以在其中输入文本。
显然,当用户在项目的textarea中输入文本时,应该保存该项目,直到项目被删除。
问题是,当我删除某个项目时,删除后的每个项目都是重新安装(为Vlad Zhukov编辑)。它只发生在我从renderItem(...)返回一个数组时(我的意思是,当我只返回item时,这个问题不会发生)。
我的问题:这是一个错误,还是一个功能?我怎样才能避免它(没有包装项目和占位符与另一个React孩子相比)?
已更新
我尝试了下一步重写renderItem(...)
:
renderItem = (item, index) => {
var Item = undefined
switch (item.type) {
case "header":
Item = Header
// a few more cases
// note that item.id is unique and static
}
// return _item -> works fine
return [
<Item key={item.id} onRemove={() => this.removeItem(item)} />,
this.state.suggested
? <Placeholder key={-item.id} />
: null
]
}
它仍然会导致问题。
答案 0 :(得分:1)
在React中重新渲染是绝对正确的,可以被认为是主要特征。当您对这些元素没有key
道具的元素数组进行更改时,在您的情况下会发生组件重新安装。
Have a look at this simple example。正如您所看到的,重新渲染组件没有区别,但删除第一个元素将清除下面的输入值。
你有两个选择:
key
设置为它(请参阅示例)。没有理由不这样做。key
。它起作用的原因是因为React内部已经使用了元素键。但是我不建议这样做,因为它对我来说看起来不够可靠,我宁愿明确控制它。