提问者:小点点

反应-不会反应。如果处理对象,PureComponent还是ComponentUpdate总是导致不重新渲染?


我发现了很多关于PureComponents的帖子,但我想知道以下几点:

如果有反应。PureComponent或shouldComponentUpdate只进行肤浅的比较——这是否意味着,如果我通过道具传递一个对象,或者将我的状态与下一个状态(这是一个对象)进行比较,那么即使该对象的属性发生了更改,也总是会导致false(因为它仍然指向同一个对象,并且没有对属性进行比较),因此,我的组件不会重新渲染吗?


共2个答案

匿名用户

是的,由于对象是相同的,所以当未调用render时,您可能会遇到这种情况。甚至官方文档也建议不要将对象值传递到PureComponent

仅当您希望有简单的道具和状态时才扩展PureComponent,或者当您知道深层数据结构已更改时才使用forceUpdate()。或者,考虑使用不可变对象来促进嵌套数据的快速比较。

但一旦您避免对传递给父组件中的props的对象进行变异,这将起作用。

如果你按照redux的减速器做的方式(一旦里面的任何东西被改变,返回新对象),你会没事的。

但由于它需要任何人的额外关注,所以更安全的做法是避免传递对象,并分解独立传递的基本值列表中的所有数据

[UPD]让我们看看父组件代码的几个例子:

此处MyPure将始终重新渲染,因为每次传递的对象不同:

render() {
    let childData = {....}; 
    ....
    return (
    .... 
        <MyPure data={childData} />

这里的MyPure将永远不会重新渲染,因为this.childData是浅层相同的:

changeChild = () => {
    this.childData.a++;
}

render() {
    ....
    return (
    ....
        <MyPure data={this.childData} />

这将工作得很好,因为我们更新不同的对象后,才更新内部的东西:

changeChild = () => {
    this.setState(oldState => ({
        childData: {
            ...oldState.childData,
            a: oldState.childData.a + 1
        }
    }));
}

render() {
    ....
    return (
    ....
        <MyPure data={this.state.childData} />

因此,我们需要遵循的限制很少:1。不要在render()(通过调用分离方法显式或隐式)2中构造数据属性。不要改变对象数据属性

匿名用户

浅层比较将是对象内第一级属性的比较。对于state,它不应该是同一个对象,因为您应该始终使用新对象调用setState。不应直接改变现有状态。