0

I'm trying to debounce a component in my webapp. Actually it is a filter for the maxPrice and if the user starts to print, the filter starts to work and all the results disappear until there is a reasonable number behind it.

What I tried so far:

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

I'm getting the error

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)

In my old version I had onChange={this.onSet} and it worked.

Any idea what might be wrong?

Preview
  • 35,317
  • 10
  • 92
  • 112
MichaelRazum
  • 789
  • 1
  • 10
  • 26

2 Answers2

3

As you mentioned in comments, it's required to use event.persist() to use event object in async way:

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.

It means such code, for example:

onChange={e => {
  e.persist();
  updateMaxPrice(e);
}}
lunochkin
  • 684
  • 4
  • 17
0

Here is my final solution. Thanks to lunochkin!

I had to introduce a second redux variable so that the user see's the values he is entering. The second variable is debounced so that the WepApp waits a bit to update.

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);
MichaelRazum
  • 789
  • 1
  • 10
  • 26