简体   繁体   English

反应:与事件侦听器关联的批处理状态更新

[英]React: Batching state updates tied to event listeners

I have a component with 'mouseover' and 'mouseout' event listeners. 我有一个带有“ mouseover”和“ mouseout”事件监听器的组件。 Several of this same component render next to one another (or overlap) in the browser, so it's possible to fire a 'mouseover', 'mouseout' and then another 'mouseover' event in that order (if you're hovering over from one element to the next) . 在浏览器中,多个相同的组件彼此相邻(或重叠)呈现,因此可以依次触发“ mouseover”,“ mouseout”和另一个“ mouseover”事件(如果您将鼠标悬停在一个元素到下一个)

The component sets state in all of those instances, but I'm wondering if there isn't a more efficient way of going about this, so as to avoid three state updates happening one after another. 该组件在所有这些实例中都设置了状态,但是我想知道是否没有一种更有效的方法来执行此操作,从而避免一次又一次发生三个状态更新。

Am I trying to unnecessarily optimize here or is this a valid concern? 我是在试图不必要地优化此处,还是这是一个有效的关注点? Here's an example of what I mean. 这是我的意思的例子。 In this case I'm just updating a count, but let's say I'm doing something more expensive like iterating over an array. 在这种情况下,我只是更新一个计数,但是可以说我正在做一些更昂贵的事情,例如遍历数组。

(Disclaimer, I haven't used the new code insertion on here and I'm having trouble running this snippet). (免责声明,我没有在这里使用新的代码插入,并且在运行此代码段时遇到了麻烦)。

 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> 

Is it necessary that the event get handled immediately? 是否有必要立即处理该事件? If not, it seems like a good use case for debouncing the handler method so that it is not invoked more frequently than X milliseconds (eg 100ms). 如果不是,则似乎是对处理程序方法进行反跳的一个好用例,以便它的调用频率不超过X毫秒(例如100ms)。 The downside of this is that the handler will wait at least that long before firing the first time. 不利的一面是,处理程序将至少等待那么长时间才能首次触发。

The Lodash library provides an implementation of debounce . 该Lodash库提供的实现去抖动

Below is how your code could be modified to use it: 下面是如何修改您的代码以使用它:

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>
    )
  }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM