【问题标题】:How can i implement debounced auto save on input change in React?如何在 React 中实现输入更改时的去抖动自动保存?
【发布时间】:2019-09-21 16:19:11
【问题描述】:

所以问题是假设您有一个编辑器。
用户一直在编辑器中输入,他会闲置一段时间,比如 5 秒。所以闲置5秒后,你向api发出网络请求,将他输入的内容保存在数据库中。它应该在空闲 5 秒后只发出一个请求。

我完成了,但它发出的请求等于字数。如果你像 asdf 这样输入,它会发出四个 api 请求。在我的例子中,四个console.log();

const EditorComponent = () => {
  const [editorState, setEditorState] = React.useState(
    EditorState.createEmpty()
  );

  // I need another logic which checks the time difference of idling.

  const debounced = () => {
    return debounce(() => {
      console.log("the api is going to call after 5 seconds");
    }, 5000);
  };

  const onEditorStateChange = value => {
    const rawContent = convertToRaw(value.getCurrentContent());
    const markdown = draftToMarkdown(rawContent);
    setEditorState(value);
    debounced()
  };

  return (
    <div style={{ width: "500px" }}>
      <Editor
        editorState={editorState}
        toolbarClassName="toolbarClassName"
        wrapperClassName="wrapperClassName"
        editorClassName="editorClassName"
        onEditorStateChange={onEditorStateChange}
      />
    </div>
  );
};

export default EditorComponent;

【问题讨论】:

  • 尝试 const debounced = debounce(() => { console.log("API 将在 5 秒后调用"); }, 5000); };
  • @VivekN 伙计,这正是我所做的。还是我错过了什么?
  • 观察他写的代码,他立即执行了 debounce,而不是放在一个函数中,你在这里所做的是你正在创建一个新的 debounce 函数,每次你调用 debounced 方法时,debounce(function ) 提供了一个可以在 onEditorStateChanged 中使用的函数

标签: javascript reactjs lodash react-hooks debounce


【解决方案1】:

问题是每次渲染都会创建一个新的去抖动函数,因此 API 会被多次调用。您必须使用useCallback 来记忆去抖动功能。如果你想在 debounced 函数中使用 editorState,你可以在调用 debounced 时从 onEditStateChange 方法传递它。您还需要更正您的 debounce 语法

const EditorComponent = () => {
  const [editorState, setEditorState] = React.useState(
    EditorState.createEmpty()
  );

  // I need another logic that checks the time difference of idling.

  const debounced = useCallback(debounce(() => {
      console.log("the api is going to call after 5 seconds");
  }, 5000), []);

  const onEditorStateChange = value => {
    const rawContent = convertToRaw(value.getCurrentContent());
    const markdown = draftToMarkdown(rawContent);
    setEditorState(value);
    debounced()
  };

  return (
    <div style={{ width: "500px" }}>
      <Editor
        editorState={editorState}
        toolbarClassName="toolbarClassName"
        wrapperClassName="wrapperClassName"
        editorClassName="editorClassName"
        onEditorStateChange={onEditorStateChange}
      />
    </div>
  );
};

export default EditorComponent;

【讨论】:

  • 我几乎可以肯定 debounced() 会将 editorState 发送到 API。所以editorState 应该设置为useCallback 的依赖项,否则debounced 将通过其关闭指向过时的值。
  • @skyboyer,这就是为什么我提到我们必须将 editorState 从 onEditorStatechange 方法传递给去抖函数,而不是依赖它的闭包,否则 useCallback 不会有任何好处
  • 是的,当然,通过参数传递editorState 也可以。但是你为什么认为闭包会消除使用useCallback 的好处?
  • @skyboyer,如果编辑器状态发生变化,回调函数会重新创建,还是原来的情况。
  • 是的,你是对的,我错了。那么将const debounced = ... 移到组件之外会更好吗?
猜你喜欢
  • 2017-01-30
  • 1970-01-01
  • 2013-11-17
  • 2017-07-01
  • 1970-01-01
  • 2022-06-16
  • 2016-07-17
  • 2019-12-31
  • 2021-10-28
相关资源
最近更新 更多