【问题标题】:ReactJS: Compare props and state on shouldComponentUpdateReactJS:在 shouldComponentUpdate 上比较道具和状态
【发布时间】:2023-03-04 21:06:01
【问题描述】:
我想检查所有属性和状态是否已更改,如果有任何更改则返回 true 并为我的所有根组件创建一个基础组件。
我想知道这是否不是最佳做法并使我的组件变慢。
另外,我所做的总是返回 true:
shouldComponentUpdate: function(newProps, newState) {
if (newState == this.state && this.props == newProps) {
console.log('false');
return false;
}
console.log('true');
return true;
},
- 我的代码有什么问题吗?
- 我应该检查 props 和 state 中的每个变量吗?
- 不会检查其中的对象会使其变慢,具体取决于它们的大小?
【问题讨论】:
标签:
javascript
reactjs
reactjs-flux
【解决方案1】:
比较 shouldComponentUpdate 中的 props 和 state 以确定是否应该重新渲染组件被认为是最佳实践。
至于为什么它总是评估为真,我相信您的 if 语句没有执行深度对象比较,而是将您以前和当前的道具和状态注册为不同的对象。
我不知道你为什么要检查两个对象中的每个字段,因为如果 props 或 state 没有改变,React 甚至不会尝试重新渲染组件,所以shouldComponentUpdate 方法的事实被称为意味着某些东西必须改变。 shouldComponentUpdate 的实现要好得多,可以检查一些 props 或 state 的变化,并据此决定是否重新渲染。
【解决方案2】:
我认为在我见过的大多数教程(包括官方文档)中,访问商店的方式都存在问题。通常我看到的是这样的:
// MyStore.js
var _data = {};
var MyStore = merge(EventEmitter.prototype, {
get: function() {
return _data;
},
...
});
当我使用这种模式时,我发现shouldComponentUpdate 等函数中的newProps 和newState 总是等于this.props 和this.state。我认为原因是商店正在返回对其可变_data 对象的直接引用。
在我的情况下,问题是通过返回 _data 的副本而不是对象本身来解决的,如下所示:
get: function() {
return JSON.parse(JSON.stringify(_data));
},
所以我会说检查您的商店并确保您没有返回对其私有数据对象的任何直接引用。
【解决方案3】:
有一个辅助函数可以有效地进行比较。
var shallowCompare = require('react-addons-shallow-compare');
export class SampleComponent extends React.Component {
shouldComponentUpdate(nextProps, nextState) {
return shallowCompare(this, nextProps, nextState);
}
render() {
return <div className={this.props.className}>foo</div>;
}
}