简单的 Debounce 在 react 16 中不起作用,但在 jsfiddle 中与 react 14.3 一起工作

simple Debounce not working in react 16 but works in jsfiddle with react 14.3

这在 React 16 中不起作用,但这个 jsfiddle 工作正常:https://jsfiddle.net/kp04015o/9/

任何人都可以调试此错误原因吗?无法读取 null 的 属性 'value',在 handleChange = debounce(e => this.setState({searchTerm: e.target.value}), 1000);

import React from 'react';
import ReactDOM from 'react-dom';

const debounce = (cb, wait) => {
  let timeout;

  return function() {
    let callback = () => cb.apply(this, arguments);

    clearTimeout(timeout);
    timeout = setTimeout(callback, wait);
  }
}

class Debounce extends React.Component {
  state = {
    searchTerm: '',
  };

  handleChange = debounce(e => this.setState({searchTerm: e.target.value}), 1000);

 render() {
   return (
     <div>
       <input type="text" onChange={this.handleChange}/>
       <div>Search Value 2: {this.state.searchTerm}</div>
     </div>
    );
  }
}

ReactDOM.render(<Debounce />, document.getElementById('root'));

我觉得我知道这个。

尝试改变这个:

<input type="text" onChange={this.handleChange} />

至:

<input type="text" onChange={this.handleChange.bind(this)} />

或:

<input type="text" onChange={(e) => this.handleChange(e)} />

这是我每次看到 React 事件的未定义内容时的直觉反应,因为您的默认状态已被处理。如果这有效,那是因为执行上下文或词法环境与它可能出现的维度不同。

了解 Event Pooling

这里有一个工作代码:

class Debounce extends React.Component {
  constructor(props) {
    super(props);

    this.handleChange = this.handleChange.bind(this);
  }

  state = {
    searchTerm: '',
  };

  setSearchTerm = debounce((searchTerm) => this.setState({ searchTerm }), 1000);

  handleChange(e) {
    this.setSearchTerm(e.target.value);
  }

  render() {
    return (
      <div>
        <input type="text" onChange={this.handleChange} />
        <div>Search Value 2: {this.state.searchTerm}</div>
      </div>
    );
  }
}

或使用 ES7 装饰器和 decko 模块更好: 从 'decko';

导入 { debounce, bind }
class Debounce extends React.Component {
  state = {
    searchTerm: '',
  };

  @debounce(1000)
  setSearchTerm(searchTerm) {
    this.setState({ searchTerm });
  }

  @bind
  handleChange(e) {
    this.setSearchTerm(e.target.value);
  }

  render() {
    return (
      <div>
        <input type="text" onChange={this.handleChange} />
        <div>Search Value 2: {this.state.searchTerm}</div>
      </div>
    );
  }
}