反应重新渲染数组而项目键没有改变

React re render array whereas item key has not changed

非常基本的列表代码示例:

class List extends React.Component {
    render() {
        const listComponent = this.props.numbers.map((number) =>
            <Item key={ number.toString() } value={ number } />,
        );

        return (
            <div>
                <button onClick={ () => this.setState({ test: 1 })}>Re-render list</button>
                { listComponent }
            </div>
        );
    }
}

这是项目:

class Item extends React.Component {
    render() {
        return (
            <div>{ this.props.value + ', rendered time:' + new Date().getTime() }</div>
        );
    }
}

当我单击按钮时,状态会更新,因此 List 组件会重新呈现。

但是,如果我的理解是正确的,那么应该不会重新渲染这些项目,因为关键项目没有改变。但它确实会重新呈现,因为时间戳已更新。

谁能解释一下为什么?

通过重新渲染一个组件,您还会在所有子组件上启动连锁反应重新渲染。

如果你希望阻止子组件重新渲染(例如,如果一些传递的道具没有改变)你可以使用生命周期方法 shouldComponentUpdate().

class Item extends React.Component {
    shouldComponentUpdate(nextProps) {
        // only re-render if props.value has changed
        return this.props.value !== nextProps.value;
    }

    render() {
        return (
            <div>{ this.props.value + ', rendered time:' + new Date().getTime() }</div>
        );
    }
}

每当你的状态改变时,整个组件都会被 React 重新渲染。如果您没有将 shouldComponentUpdate() 函数设置为 return false,则默认为 true。看看 React's component lifecycle.

你的理解完全错误

key 的全部目的是 ordering 而不是 rendering。 假设您有项目 a、b、c、d 并通过开关 a 和 c 对它们重新排序,即 c、b、a、d。 没有密钥,React 就很难弄清楚如何从旧虚拟 DOM 转换为新虚拟 DOM。

请阅读本文 https://facebook.github.io/react/docs/lists-and-keys.html