使用setTimeout避免在React中重新渲染

问题描述 投票:3回答:2

我经常使用一种模式,我认为必须是一种反模式,但我不知道更好的选择。

有时,我的组件可能会收到一个或多个意味着需要重新渲染的事件。有时情况是我不知道将调用事件处理程序的次数。为了防止多次重新渲染由于多次调用处理程序,我做了类似这样的事情:

 _myEventHandler() { // may be called multiple times between renders
   if (!this._updateQueued) {
     this._updateQueued = true;
     this._updateTimer = setTimeout(() => {
       this._updateQueued = false;
       this.forceUpdate();
     }, 0);
   }
 }

这里的问题是我觉得由于代码停止和事件循环启动之间的延迟而无法实现性能。

一个现实世界的例子就是当我使用react-visibility-sensor并且我有多个元素一次改变它们的可见性时,我不想为每个元素重新渲染,而是我只想重新渲染一次已收到更新。

还有另一种更好的方式来处理多个电话吗?

顺便说一句:如果你打算使用上面的黑客,别忘了在你的clearTimout(this._updateQueued)中打电话给componentWillUnmount

reactjs settimeout anti-patterns
2个回答
1
投票

去抖动将减少某段代码运行的次数,无论它被调用的频率如何。这是一个相当简单的实现。

const debounce = (callable, time) => {
  let timeout;

  return function() {
    const functionCall = () => callable.apply(this, arguments);

    clearTimeout(timeout);
    timeout = setTimeout(functionCall, time);
  };
};

这就是如何使用它。

const debouncedIteration = debouce(() => {
   console.log("Iteration"); // This will be called once every 1000 milliseconds.
}, 1000);

while (true) {
   debouncedIteration();
}

1
投票

您可以使用此生命周期方法shouldComponentUpdate避免重新渲染(如@fungusanthrax所述)。将其保留在您的反应组件中:

shouldComponentUpdate(nextProps, nextState) {
  return !isEqual(this.props, nextProps) || !isEqual(this.state, nextState);
}

在这里使用来自lodash的isEqual,请确保包含它。这只会在道具或州值发生变化时重新渲染您的组件。

要安装lodash:

npm install -S lodash

并在组件文件中导入isEqual:

import isEqual from 'lodash/isEqual';
© www.soinside.com 2019 - 2024. All rights reserved.