reactjs - 添加去抖动后数据已停止返回
问题描述
我正在根据用户输入进行 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>
);
}
当我控制台记录数据时,它会返回未定义,即使我可以在网络请求中看到数据。
有任何想法吗
解决方案
您不能等待 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>
推荐阅读
- java - Thymeleaf 连接对象的属性名称相同的输入字段的值
- html - “必需”html标签上的vue 3 / vitejs / volar项目中的打字稿错误
- keras - keras 中的评估生成器
- postgresql - 是否有社区制作的 PostgreSQL 函数/片段的存储库?
- ionic-framework - 无限循环角火库和离子复选框
- python - 分解正弦波但相位有时似乎不匹配
- mongodb - 在 Mongoose 中,Model.find() 和 Model.find().exec() 产生相同的结果。那么为什么还要使用 Model.find().exec() 呢?
- c - 如何解决我的代码中“->”令牌之前的错误“预期的')'?
- c# - Xamarin 公共类数据如何正确访问它
- python - Pyinstaller Matplotlib [Errno 2] 没有这样的文件或目录:'C:\\Users\\Tobi\\AppData\\Local\\Temp\\_MEI142562\\matplotlib\\mpl-data\\matplotlibrc'