反应/ redux去抖节流

react / redux debounce throttling

我正在尝试对我的网络应用程序中的一个组件进行去抖动。实际上它是 maxPrice 的过滤器,如果用户开始打印,过滤器就会开始工作,所有结果都会消失,直到它后面有一个合理的数字。

到目前为止我尝试了什么:

import _ from 'lodash'

class MaxPrice extends Component {
  onSet = ({ target: { value }}) => {
    if (isNaN(Number(value))) return;

    this.setState({ value }, () => {
        this.props.updateMaxPrice(value.trim());
    });
  };

  render() {
    const updateMaxPrice = _.debounce(e => {
      this.onSet(e);
    }, 1000);

    return (
      <div>
        <ControlLabel>Preis bis</ControlLabel><br />
        <FormControl type="text" className={utilStyles.fullWidth} placeholder="egal"
          onChange={updateMaxPrice} value={this.props.maxPrice}
        />
      </div>
    );
  }
}

我遇到错误

MaxPrice.js:11 Uncaught TypeError: Cannot read property 'value' of null
at MaxPrice._this.onSet (MaxPrice.js:11)
at MaxPrice.js:21
at invokeFunc (lodash.js:10350)
at trailingEdge (lodash.js:10397)
at timerExpired (lodash.js:10385)

在我的旧版本中,我有 onChange={this.onSet} 并且它有效。

知道哪里出了问题吗?

正如您在评论中提到的,需要使用 event.persist() 以异步方式使用事件对象:

https://facebook.github.io/react/docs/events.html

If you want to access the event properties in an asynchronous way, you should call event.persist() on the event, which will remove the synthetic event from the pool and allow references to the event to be retained by user code.

表示这样的代码,例如:

onChange={e => {
  e.persist();
  updateMaxPrice(e);
}}

这是我的最终解决方案。感谢 lunochkin!

我不得不引入第二个 redux 变量,以便用户看到他输入的值。第二个变量是去抖动的,这样 WepApp 会稍等片刻才能更新。

class MaxPrice extends Component {

  updateMaxPriceRedux = _.debounce((value) => { // this can also dispatch a redux action
      this.props.updateMaxPrice(value);
  }, 500);

  onSet = ({ target: { value }}) => {
    console.log(value);
    if (isNaN(Number(value))) return;
    this.props.updateInternalMaxPrice(value.trim());
    this.updateMaxPriceRedux(value.trim());
  };

    render() {
        return (
            <div>
                <ControlLabel>Preis bis</ControlLabel><br />
                <FormControl type="text" className={utilStyles.fullWidth} placeholder="egal"
                             onChange={e => {
                                 e.persist();
                                 this.onSet(e);
                             }} value={this.props.internalMaxPrice}
                />
            </div>
        );
    }
}

function mapStateToProps(state) {
    return {
        maxPrice: state.maxPrice,
        internalMaxPrice: state.internalMaxPrice
    };
}
function mapDispatchToProps(dispatch) {
    return bindActionCreators({updateMaxPrice:updateMaxPrice,
        updateInternalMaxPrice:updateInternalMaxPrice}, dispatch);
}
export default connect(mapStateToProps, mapDispatchToProps)(MaxPrice);