react 合成事件中的异步处理

若是直接将事件处理函数(其中须要修改state)进行debounce装饰就会报以下错误,css

The SyntheticEvent is pooled. This means that the SyntheticEvent object will be reused and all properties will be nullified after the event callback has been invoked. This is for performance reasons. As such, you cannot access the event in an asynchronous way.
SyntheticEvent 对象是经过合并获得的。 这意味着在事件回调被调用后,SyntheticEvent 对象将被重用而且全部属性都将被取消。这是出于性能缘由。所以,您没法以异步方式访问该事件。

由于react中的event是池化的合成事件,debounce处理后就是异步操做,因此再次获取event 是空对象。所以将过程拆解,handleEvent 照常处理event 对象再将修改state的操做进行防抖便可。react

import React from "react";
import ReactDOM from "react-dom";
import { debounce, get } from "lodash";

import "./styles.css";

export class MyComponent extends React.Component {
  constructor(props) {
    super(props);
    this.state = {};
    this.genDebounceFn = this.genDebounceFn.bind(this);
  }

  handleEvent(e) {
    const newState = {
      ...this.state
    };
    // 这里引用了SyntheticEvent event 对象的type 方法
    newState[e.type] = get(this.state, e.type, 0) + 1;
    this.modifyState.call(this, newState);
  }

  componentWillReceiveProps(nextProps) {
    this.genDebounceFn(nextProps);
  }

  componentDidMount() {
    this.genDebounceFn(this.props);
  }

  genDebounceFn(props) {
    this.modifyState = debounce(newState => {
      this.setState(() => newState);
    }, props.delay);
  }

  render() {
    const eventCount = Object.keys(this.state).map(e => {
      return (
        <div key={e}>
          {e}:{this.state[e]}
        </div>
      );
    });
    return (
      <>
        delay: {this.props.delay}
        <br />
        <span>{eventCount}</span>
        <button
          onClick={this.handleEvent.bind(this)}
          onMouseOver={this.handleEvent.bind(this)}
        >
          click me OR mouseOver me
        </button>
      </>
    );
  }
}

点击预览dom

相关文章
相关标签/搜索