【发布时间】:2021-06-17 00:53:14
【问题描述】:
使用 debounce 函数实现,没有 lodash 来自下面的要点
- utils.js
export const debounce = (fn, delay) => {
let timer = null;
return function (...args) {
const context = this;
timer && clearTimeout(timer);
timer = setTimeout(() => {
fn.apply(context, args);
}, delay);
};
}
- 标题
import React, { useEffect, useRef, useState, useContext } from 'react';
import SearchContext from "../Search/context"
import { debounce } from "../../utils";
function Header() {
const [searchBox, setSearchBox] = useState(false)
const ref = useRef(null)
const inputRef = useRef(null)
const { searchInput, updateSearchInput } = useContext(SearchContext)
...
render(
...
<input className="searchInput"
ref={inputRef}
value={searchInput}
onChange={(e) => debounce(updateSearchInput(e.currentTarget.value), 2000)}
onBlur={() => setSearchBox(false)}
type="text" maxLength="80" />
...
)
}
export default Header;
- 搜索
import React, { useContext, useRef, useEffect, useState, useCallback } from "react"
import { debounce } from "../../utils";
import searchContext from "../Search/context"
import { apiCallMethod} from "../../api"
const Search = () => {
const context = useContext(searchContext)
const [results, setResults] = useState(null)
// context.searchInput is the value of the input box provided by SearchContext.Provider
const fetchData = useCallback(async () => {
// the input string is the query param for the api request
return await apiCallMethod(context.searchInput, null).then(response => {
setResults(response.results)
})
}, [context]);
useEffect(() => {
debounce(fetchData(), 2000)
return () => setResults(null)
}, [fetchData])
render(...)
}
export default Search
上面的组件发生了一些事情
由于我的应用程序相当大,我没有直接从 html input onChange 事件进行 API 调用。
我有一个反应上下文挂钩设置为searchContext,它存储在input 框中输入的文本值
通过上下文提供程序将相同的字符串提供给Search组件,它被称为context.searchInput
在Search 中,有一个useEffect() 调用了返回渲染响应数据的Api 方法。
但是,debounce 没有按预期工作。它有时不会返回正确的结果,因为
- 结果集不代表最近输入的字符串,并且
- chrome devtools 显示它在 debounce 之前触发了对子字符串的过多请求
我尝试将debounce 包装在onChange 中,在Header 组件中,在Search 组件中,并同时包装两者。我也尝试将延迟从500 增加到2000,但没有帮助。
如果有副作用,我也可以删除 useCallback 挂钩。感谢反馈
参考文献
去抖实现 1 https://gist.github.com/simonw/c29de00c20fde731243cbac8568a3d7f
去抖实现 2 https://gist.github.com/sachinKumarGautam/6f6ce23fb70eec5d03e16b504b63ae2d
【问题讨论】:
-
我不想详细说明您的问题,但是,我也遇到了 debounce 问题,这可能对 stackoverflow.com/questions/65457979/… 有所帮助。答案中的实现按预期工作。
标签: javascript reactjs async-await react-hooks