简体   繁体   English

setState 完成后如何去抖动表单中的更改

[英]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.所以首先,我在我的 handleChange 方法中添加了 debounce,因为如果你输入的速度非常快,你可以移动到另一个字段并继续前进,第一个字段不会更新它的状态。

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.我对如何让它更新状态感到非常困惑,即使用户已经继续前进并继续在下一个字段中输入,以及在输入中断时自动保存到 db 也是如此。

// 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.为了将表单的变化去抖到 api,你不需要去抖状态更新,而是在状态变化时调用的 api 调用。 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.在这个 wat 中,用户更新哪个字段并不重要,去抖动只会应用于 api 调用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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