React 16强制组件在返回数组时重新渲染

时间:2017-11-06 09:30:43

标签: javascript reactjs mobx-react

假设我在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
    ]
}

它仍然会导致问题。

1 个答案:

答案 0 :(得分:1)

在React中重新渲染是绝对正确的,可以被认为是主要特征。当您对这些元素没有key道具的元素数组进行更改时,在您的情况下会发生组件重新安装

Have a look at this simple example。正如您所看到的,重新渲染组件没有区别,但删除第一个元素将清除下面的输入值。

你有两个选择:

  1. 使用组件而不是数组并将key设置为它(请参阅示例)。没有理由不这样做。
  2. 删除所有key。它起作用的原因是因为React内部已经使用了元素键。但是我不建议这样做,因为它对我来说看起来不够可靠,我宁愿明确控制它。