简体   繁体   中英

How to debounce the changes in a form after setState is done

Having a hard time figuring this out. Some others helped me debounce the other day, but turns out I'm actually debouncing on each keystroke now, which causes an unacceptable lag while typing.

So first, I added debounce to my handleChange method, because if you typed very fast, you could move on to another field and keep going, and the first field would not update it's state.

Then, I made a timeout for each element, so it would finish, even if you moved on. But then I noticed an unacceptable lag while typing.

I'm very confused on how to make it update the state, even if the user has moved on and kept typing into the next field, as well as also autosave to db once a break in typing occurs.

// editingTimeout should be an object in the state
handleChange = (e) => {
  const targetName = e.target.name;
  const targetValue = e.target.value;

  this.setState(state => {
    clearTimeout(this.state.editingTimeout[targetName]);
    return ({
      editing: false,
      editingTimeout: {
        ...state.editingTimeout,
        [targetName]: setTimeout(() => {
          console.log(`${targetName}: ${targetValue}`);
          this.setState({
            [targetName]: targetValue,
          });
        }, 300),
      }
    })
  });
};

In order to debounce the changes of a form to an api, you don't need to debounce the state update, but the api call that is being called when the state changes. What I do is, update the state and then call a function that sends the changes to the server like this:

import debounce from 'debounce';

class ComponentA extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      name: '',
      email: '',
    }
  }
  
  handleInputChange = (e) => {
    this.setState({ [e.target.name]: e.target.value }, () => this.update())
  }


  update = debounce(() => {
    const data = {
      name: this.state.name,
      email: this.state.email,
    }
    this.props.updateApiCall(data);
  }, 1000);
  
  render () {
    return (
      <div>
        <input name='name' onChange={this.handleInputChange} value={this.state.name} />
        <input name='email' onChange={this.handleInputChange} value={this.state.email} />
      </div>
    )
  }
}

In this wat, it doesn't matter which field the user is updating, the debounce will only be applied to the api call.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM