我已经阅读了很多次这个问题,并且每次建议的答案都是不要使用深度比较,因为这样做代价高昂。我已经尝试在我的应用程序中实现它,而且确实确实非常快。
shouldComponentUpdate = (nextProps, nextState) => {
let a = +new Date();
let equalProps = _.isEqual(this.props, nextProps);
let equalState = _.isEqual(this.state, nextState);
let b = +new Date();
console.log("----> deep equality navbar took ", b - a, " result = ", equalProps && equalState);
if (equalProps && equalState) return false;
return true;
};
这是生成的日志示例:
----> deep equality msg list took 0 result = false
----> deep equality msg list took 0 result = false
----> deep equality navbar took 0 result = true
----> deep equality sidebar took 0 result = true
----> deep equality msg list took 1 result = false
基本上,它似乎永远不会超过1毫秒,而我正在处理一些6/7级嵌套对象。消息列表的呈现通常需要70毫秒以上的时间。.我可以通过少于1毫秒的函数调用轻松避免这种情况。
我在这里想念一些大事吗?真是个好主意..烤我:)
答案 0 :(得分:0)
这是因为您使用的是小样本数据,所以您没有发现任何速度问题,如果有要比较的大数据,那将是大问题,因为componentshouldupdate
在每个状态下运行,因此如果{{1} }会花费一些时间,这会降低反应页面的渲染速度
您可以在下面的对象比较列表中找到并投影一个击球手
lodash.isEqual
答案 1 :(得分:0)
您无需在state
或prop
更改中一遍又一遍地比较大型数据集,而可以简单地利用并与日期对象进行比较,以使组件知道是否需要重新呈现它。例如,如果retrieved
数据发生更改,则messages
日期对象可能会更新;现在,与其进行大数据比较,不如将其与自身进行比较:
class MessageList extends Component {
state = {
retrieved: {},
messages: [],
err: ''
}
fetchMessages = () => {
this.props.fetchMessages()
.then(({data}) => this.setState({ messages: data, retrieved: new Date() }))
.catch(err => this.setState({ err: err.toString() }))
shouldComponentUpdate = (nextProps, nextState) => (
nextState.retrieved > this.state.retrieved || nextState.err !== this.state.err
) // this would compare a retrieved date and/or an err; it will only rerender if either has changed
render = () => ( ... )
}
这将在浏览器和不同设备上保持一致,即使您的应用程序进行扩展以包含更多数据,更多道具和更多状态。