我有一个纯组件,它带有一个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创建单独的道具来克服此问题?
答案 0 :(得分:0)
在您的情况下,直接更改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} />;
}
}
在上述情况下,MyPureComponent
是PureComponent
时,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
。