是否可以在React中将深度嵌套的JSON对象传递给PureComponent属性?

时间:2019-09-20 09:37:09

标签: reactjs react-native

我有一个纯组件,它带有一个prop,基本上是一个深嵌套的JSON对象,如下所示:

const jsonObject = {
  prop1: {
    arrayProp: [],
  },
  prop2: 'string',
  prop3: {
    anotherprop: {
      someanotherprop1: {},
      someanotherprop2: {
        someArrayProp: [],
      },
    },
  },
};

注意实际上,该对象更深,但是为了简单起见,我提供了一个更简单的对象。


然后将其传递给父组件中的纯组件,如下所示:

class App extends React.Component {
      updateJSON = () => {
        const { jsonObject } = this.state;

        const updatedObject = _.cloneDeep(jsonObject);

        updatedObject.prop3.anotherprop.someanotherprop2.someArrayProp = [1, 2, 3];

        this.setState({ jsonObject: updatedObject });
      }


      render() {
        const { jsonObject } = this.state;
        return (
          <View>
            <MyPureComponent layout={jsonObject} />
            <TouchableOpacity onPress={this.updateJSON} />
          </View>
        );
      }
    }

例如,如果我使用setState更改someArrayProp数组,我的purecomponent是否会更新?

对于这种特殊情况,我可以自己进行测试,但这是一个关于PureComponent如何对此类深层对象进行浅层比较的通用问题。

据我了解,纯组件具有内置的componentShouldUpdate钩子,该钩子对props进行了浅浅的比较,并确定是否应更新该组件。

这使我认为,由于我的道具是深深嵌套的,因此有时可能会错过组件的更新,因为它可能无法检测到JSON树中某处的更改。

我真的应该为此担心并实现我的on componentShouldUpdate函数来检查差异吗? 还是应该基于深度嵌套的JSON创建单独的道具来克服此问题?

1 个答案:

答案 0 :(得分:0)

stateprops需要被视为不可变

在您的情况下,直接更改someArrayProp而不创建新实例将不会导致渲染。

class App extends React.Component {
  render() {
    const { jsonObject } = this.state;

    // Some logic changing `jsonObject` like:
    jsonObject.prop3.anotherprop.someanotherprop2.someArrayProp = ['hello'];


    return <MyPureComponent layout={jsonObject} />;
  }
}

在上述情况下,MyPureComponentPureComponent时,shallow comparison将比较相同的引用。

class MyPureComponent extends PureComponent {

  /* PureComponent implements shallow comparison by default

  shouldComponentUpdate(nextProps) {
     return this.props.layout !== next.props.layout;
  }

  */

  render() {}
}

这就是the best practice is not mutating data的原因。

class App extends React.Component {
  render() {
    const { jsonObject } = this.state;

    // Some logic changing deep nested entry
    const someArrayChanged = ...;

    return <MyPureComponent layout={{ ...jsonObject, ...someArrayChanged }} />;
  }
}
  

我真的应该为此担心并实现自己的componentShouldUpdate函数来检查差异吗?还是应该基于深度嵌套的JSON创建单独的道具来克服此问题?

答案取决于如何突变数据(如果直接突变的话)-您应该实现自己的componentShouldUpdate,否则,您不必担心。

通常,当组件由于默认componentShouldUpdate的失败而导致不必要的渲染时,将使用shallow comparison