返回数组时反应 16 力组件 re-render

React 16 forces component re-render while returning array

假设我在 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 处理程序。每个组件都有文本区域,用户可以在其中输入文本。

显然,当用户在项目的文本区域内输入文本时,应该保存它直到项目被删除。

问题是当我删除一些项目时,删除项目之后的每个项目都被重新安装(为 Vlad Zhukov 编辑)。只有当我 return 来自 renderItem(...) 的数组时才会发生(我的意思是,当我 return 只有项目时,这个问题不会发生)。

我的问题:这是一个错误,还是一个功能?我怎样才能避免它(最好不要用另一个 React child 包装 item 和 Placeholder)?


已更新

我尝试用下一种方式重写 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
    ]
}

它仍然会导致问题。

重新渲染在 React 中绝对没问题,可以被认为是主要功能。在你的情况下发生的是组件 remount 当你对元素数组进行更改时这些元素没有 key 道具。

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

您有 2 个选择:

  1. 使用组件而不是数组并为其设置 key(参见示例)。真的没有理由不去。
  2. 删除所有 key。它之所以有效,是因为 React 内部已经为元素使用了键。但是我不建议这样做,因为它对我来说看起来不够可靠,我更愿意明确地控制它。