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

相關文章
相關標籤/搜索