Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/444.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 为什么我应该避免在shouldComponentUpdate中使用u.isEqual_Javascript_Html_Reactjs - Fatal编程技术网

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

Javascript 为什么我应该避免在shouldComponentUpdate中使用u.isEqual,javascript,html,reactjs,Javascript,Html,Reactjs,这个问题我已经读了很多遍,每次建议的答案都是不要进行深入的比较,因为这样做代价高昂。我已经尝试在我的应用程序中实现这一点,它看起来确实非常快 shouldComponentUpdate = (nextProps, nextState) => { let a = +new Date(); let equalProps = _.isEqual(this.props, nextProps); let equalState = _.isEqual(this.state,

这个问题我已经读了很多遍,每次建议的答案都是不要进行深入的比较,因为这样做代价高昂。我已经尝试在我的应用程序中实现这一点,它看起来确实非常快

  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毫秒的函数调用轻松避免


我错过了一件大事?这似乎是真的。。烤我:

这是因为您使用的是小样本数据,所以没有发现任何速度问题,如果有大数据要比较,那么这将是一个大问题,因为组件应该在每次状态更新时运行更新,所以如果lodash.isEqual需要一些时间,它将降低页面渲染速度

您可以在下面看到一个对象比较列表,并找到您项目的最佳对象

fast-deep-equal x 226,960 ops/sec ±1.55% (86 runs sampled)
nano-equal x 218,210 ops/sec ±0.79% (89 runs sampled)
shallow-equal-fuzzy x 206,762 ops/sec ±0.84% (88 runs sampled)
underscore.isEqual x 128,668 ops/sec ±0.75% (91 runs sampled)
lodash.isEqual x 44,895 ops/sec ±0.67% (85 runs sampled)
deep-equal x 51,616 ops/sec ±0.96% (90 runs sampled)
deep-eql x 28,218 ops/sec ±0.42% (85 runs sampled)
assert.deepStrictEqual x 1,777 ops/sec ±1.05% (86 runs sampled)
ramda.equals x 13,466 ops/sec ±0.82% (86 runs sampled)
The fastest is fast-deep-equal

您可以简单地利用日期对象并与之进行比较,让组件知道是否需要重新提交,而不是在状态或属性更改时反复将大型数据集与自身进行比较。例如,如果消息数据发生更改,则可以更新检索到的日期对象;现在,与其进行大数据比较,不如将其与自身进行比较:

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 = () => ( ... )

 }

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

谢谢您的回答,但我不会使用小样本数据。我正在使用webmail项目中的生产数据。消息列表实际上包含50封完整的电子邮件和许多其他东西…,边栏作为道具接收~1000个文件夹、标签等。。。这些实体中的每一个都是嵌套的,复杂的对象在聚会上有点晚,但这仍然是一个相当小的样本量。我曾经开发过一个react/redux应用程序,它每分钟处理数百万条消息,甚至与某些应用程序的要求不符。@GMchris我对这种情况下的性能很好奇,如果使用isEqual,还可以吗?例如,将以前的状态与当前状态进行比较?@SangĐặ我想说,你需要有点选择性。我使用recompose的shouldUpdate方法制作了这个包装器const propsEqual=props=>shouldUpdatecurr,next=>{if!props返回!\uu.isEqualcurr,next;对于let i=0,prop;i