React-如果处理对象,React.PureComponent或shouldComponentUpdate是否总是导致不重新渲染?

时间:2018-11-12 12:10:44

标签: reactjs

我发现了很多有关PureComponents浅层比较的文章,但想知道以下几点:

如果React.PureComponent或shouldComponentUpdate仅做浅层比较-这并不意味着如果我通过prop传递对象或将我的状态与nextState(这是一个对象)进行比较,即使该对象的属性为false,也总是会导致错误已经更改(因为它仍然指向同一个对象并且没有完成属性的比较),因此,我的组件不会重新渲染?

2 个答案:

答案 0 :(得分:1)

是的,由于对象相同,可能不调用render时会遇到麻烦。甚至官方文档也建议不要将对象值传递到PureComponent中。

  

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

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

如果您按照redux的reducers的方式进行操作(一旦内部内容发生更改,就返回新对象),就可以了。

但是又一次,因为它需要任何人的额外关注,所以它更安全,只是避免传递对象并爆炸独立传递的原始值列表中的所有数据

[UPD]让我们看一下有关Parent组件代码的几个示例:

这里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.不要更改对象数据道具

答案 1 :(得分:0)

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