首页 > 解决方案 > 添加去抖动后数据已停止返回

问题描述

我正在根据用户输入进行 API 调用 onChange。我添加了一个去抖动功能,所以它只对每个单词提出请求。我正在以反应最终形式 FormSpy 执行此操作,因为这对其他领域也有影响。

import { FormSpy } from 'react-final-form';
import { OnChange } from 'react-final-form-listeners';
import _ from 'lodash';

function Component({
  handleFunction,
  input,
}: {
  handleFunction: any;
  input: any;
}) {
  const debouncedSave = useCallback(
    _.debounce(async (newValue) => await getSuggestedSections(newValue), 1000),
    [],
  );
  return (
    <FormSpy subscription={{ dirty: true, values: true }}>
      {() => (
        <OnChange name="item-name">
          {async (value) => {
            const data = await debouncedSave(value);
            console.log(value);
            console.log(data);
          }}
        </OnChange>
      )}
    </FormSpy>
  );
}

当我控制台记录数据时,它会返回未定义,即使我可以在网络请求中看到数据。

有任何想法吗

标签: reactjslodashdebouncing

解决方案


您不能等待 useCallback 函数,为了解决这个问题,我将在 useCallback 中处理 promise 的解析,并使用一个 use 效果,该效果依赖于在 useCallback 中更新的状态。

请参阅下面的可运行示例。忽略脚本错误,我通过脚本标签包含了 babel 运行时以允许代码片段中的异步函数。

async function getSuggestedSections(value) {
  return new Promise((resolve) => setTimeout(resolve(value), 2000));
}

function ExampleComponent() {
  const [value, setValue] = React.useState("");
  const [data, setData] = React.useState(null);

  const debounceSave = React.useCallback(
    _.debounce(async (newValue) => {
      const data = await getSuggestedSections(newValue);
      setData(data);
      return data;
    }, 1000),
    []
  );

  const handleOnChange = async (evt) => {
    const { value } = evt.target;
    setValue(value);
    await debounceSave(value);
  };

  React.useEffect(() => {
    if (data) {
      console.log(`returned: ${data}`);
      // do stuff with data
    }
  }, [data]);

  return (
    <div>
      <input type="text" value={value} onChange={handleOnChange} />
    </div>
  );
}

ReactDOM.render(<ExampleComponent />, document.getElementById('root'));
<script src="https://unpkg.com/@babel/standalone@7/babel.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.0/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.0/umd/react-dom.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.21/lodash.min.js" integrity="sha512-WFN04846sdKMIP5LKNphMaWzU7YpMyCU245etK3g/2ARYbPK9Ub18eG+ljU96qKRCWh+quCY7yefSmlkQw1ANQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<div id="root"></div>


推荐阅读