【问题标题】:React re render array whereas item key has not changed反应重新渲染数组,而项目键没有改变
【发布时间】:2018-01-03 23:42:50
【问题描述】:

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

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 组件会重新呈现。

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

谁能解释一下为什么?

【问题讨论】:

    标签: arrays reactjs rerender


    【解决方案1】:

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

    如果您希望阻止子组件重新渲染(例如,如果某些传递的道具没有改变),您可以使用生命周期方法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>
            );
        }
    }
    

    【讨论】:

    • 我明白这一点,但是为数组项设置关键属性有什么意义呢?
    • 我的理解是,这些键只是一个性能优化,用于比较列表项是否有任何变化。与重新渲染或不重新渲染无关。以下是关于为什么需要密钥的深入解释:facebook.github.io/react/docs/…
    【解决方案2】:

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

    【讨论】:

      【解决方案3】:

      你的理解完全错误

      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

      【讨论】:

        猜你喜欢
        • 2021-12-09
        • 1970-01-01
        • 2019-11-19
        • 1970-01-01
        • 2023-02-16
        • 2019-06-05
        • 1970-01-01
        • 1970-01-01
        • 2022-07-08
        相关资源
        最近更新 更多