【问题标题】:React: Batching state updates tied to event listenersReact:批处理与事件侦听器相关的状态更新
【发布时间】:2018-12-05 04:53:29
【问题描述】:

我有一个带有“mouseover”和“mouseout”事件监听器的组件。几个相同的组件在浏览器中彼此相邻(或重叠)呈现,因此可以按顺序触发 'mouseover'、'mouseout' 和另一个 'mouseover' 事件(如果你在悬停从一个元素到下一个元素)

组件在所有这些实例中设置状态,但我想知道是否没有更有效的方法来解决这个问题,以避免三个状态更新相继发生。

我是否试图在这里进行不必要的优化,或者这是一个有效的问题?这是我的意思的一个例子。在这种情况下,我只是更新一个计数,但假设我正在做一些更昂贵的事情,比如遍历一个数组。

(免责声明,我没有在这里使用新的代码插入,我在运行这个 sn-p 时遇到了问题)。

import React, { Component } from 'react';

class DummyComponent extends Component {
  state = {
    someProp: 1
  };
  
  componentDidMount() {
    this.addEventListener('mouseover', this.handleEvent);
    this.addEventListener('mouseout', this.handleEvent);
  }
  
  componentWillUnmount() {
    this.removeEventListener('mouseover', this.handleEvent);
    this.removeEventListener('mouseout', this.handleEvent);
  }
  
  handleEvent(event) {
    console.log(event.type);
    this.setState({ someProp: this.state.someProp += 1 });
  };
  
  render() {
    return (
      <section>
        {this.state.someProp}
      </section>
    )
  }
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>

【问题讨论】:

标签: javascript reactjs


【解决方案1】:

是否有必要立即处理该事件?如果不是这样,这似乎是一个很好的用例来消除处理程序方法的抖动,这样它的调用频率就不会超过 X 毫秒(例如 100 毫秒)。这样做的缺点是处理程序将在第一次触发之前至少等待那么长时间。

Lodash 库提供了debounce 的实现。

以下是如何修改您的代码以使用它:

import React, { Component } from 'react';
import _ from 'lodash';

class DummyComponent extends Component {
  state = {
    someProp: 1
  };

  componentDidMount() {
    this.addEventListener('mouseover', this.debouncedHandleEvent);
    this.addEventListener('mouseout', this.debouncedHandleEvent);
  }

  componentWillUnmount() {
    this.removeEventListener('mouseover', this.debouncedHandleEvent);
    this.removeEventListener('mouseout', this.debouncedHandleEvent);
  }

  handleEvent(event) {
    console.log(event.type);
    this.setState({ someProp: this.state.someProp += 1 });
  };

  // Debounced handler with a wait time of 100ms
  debouncedHandleEvent = _.debounce(handleEvent, 100)

  render() {
    return (
      <section>
        {this.state.someProp}
      </section>
    )
  }
}

【讨论】:

    猜你喜欢
    • 2012-07-31
    • 2021-08-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-08-06
    • 2016-06-02
    • 2022-10-01
    • 2021-07-18
    相关资源
    最近更新 更多