首页 > 解决方案 > 如何去抖动一个函数,在 React 中使用 onChange 时会立即调用另一个函数?

问题描述

问题

当用户选中/取消选中复选框时,会通过onChange事件发出发布请求。为了避免敲击 API,我使用_.debounce。但是,我想在事件触发state时立即更新。onChange

我知道我当前的代码不允许这样做,因为我正在更新statein updateTodoItem(),它在debouncedhandleChange()函数中运行。

问题。

如何在即时调用时继续对发布请求进行去抖动this.setState()

简化代码

...
import _ from "lodash";
import axios from "axios";
import setAxiosHeaders from "./AxiosHeaders";
class TodoItem extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      complete: this.props.todoItem.complete
    };
    this.handleChange = this.handleChange.bind(this);
    this.updateTodoItem = this.updateTodoItem.bind(this);
    this.inputRef = React.createRef();
    this.completedRef = React.createRef();
    this.path = `/api/v1/todo_items/${this.props.todoItem.id}`;
  }
  handleChange() {
    this.updateTodoItem();
  }
  updateTodoItem() {
    this.setState({
      complete: this.completedRef.current.checked
    });
    setAxiosHeaders();
    axios
      .put(this.path, {
        todo_item: {
          title: this.inputRef.current.value,
          complete: this.completedRef.current.checked
        }
      })
      .then(response => {})
      .catch(error => {
        console.log(error);
      });
  }
  render() {
    const { todoItem } = this.props;
    return (
      <tr className={`${this.state.complete ? "table-light" : ""}`}>
        <td>
          ...
        </td>
        <td className="text-right">
          <div className="form-check form-check-inline">
            <input
              type="boolean"
              defaultChecked={this.state.complete}
              type="checkbox"
              onChange={_.debounce(this.handleChange, 1000)}
              ref={this.completedRef}
              className="form-check-input"
              id={`complete-${todoItem.id}`}
            />
            <label
              className="form-check-label"
              htmlFor={`complete-${todoItem.id}`}
            >
              Complete?
            </label>
          </div>
        </td>
      </tr>
    );
  }
}

export default TodoItem;

标签: reactjs

解决方案


我只需要打电话_.debounce()updateTodoItem

handleChange() {
  this.setState({
    complete: this.completedRef.current.checked
  });
  this.updateTodoItem();
}
updateTodoItem = _.debounce(() => {
  setAxiosHeaders();
  axios
    .put(this.path, {
      todo_item: {
        title: this.inputRef.current.value,
        complete: this.completedRef.current.checked
      }
    })
    .then(response => {})
    .catch(error => {
      console.log(error);
    });
}, 1000);
<input
  type="boolean"
  defaultChecked={this.state.complete}
  type="checkbox"
  onChange={this.handleChange}
  ref={this.completedRef}
  className="form-check-input"
  id={`complete-${todoItem.id}`}
/>;

推荐阅读