为什么我应该避免在shouldComponentUpdate中使用_.isEqual

时间:2018-10-23 13:02:26

标签: javascript html reactjs

我已经阅读了很多次这个问题,并且每次建议的答案都是不要使用深度比较,因为这样做代价高昂。我已经尝试在我的应用程序中实现它,而且确实确实非常快。

  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毫秒的函数调用轻松避免这种情况。

我在这里想念一些大事吗?真是个好主意..烤我:)

2 个答案:

答案 0 :(得分:0)

这是因为您使用的是小样本数据,所以您没有发现任何速度问题,如果有要比较的大数据,那将是大问题,因为componentshouldupdate在每个状态下运行,因此如果{{1} }会花费一些时间,这会降低反应页面的渲染速度

您可以在下面的对象比较列表中找到并投影一个击球手

lodash.isEqual

https://github.com/epoberezkin/fast-deep-equal

答案 1 :(得分:0)

您无需在stateprop更改中一遍又一遍地比较大型数据集,而可以简单地利用并与日期对象进行比较,以使组件知道是否需要重新呈现它。例如,如果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 = () => ( ... )

 }

这将在浏览器和不同设备上保持一致,即使您的应用程序进行扩展以包含更多数据,更多道具和更多状态。