React函数钩子的用法
记录一下今天在用lodash做防抖的时候出现的问题,
其实也算是React知识的查漏补缺了,主要是对useCallback和useMemo的回顾,以及Github REST api的一些使用。
因为github的api对接口进行限流,所以在输入文字的时候查询的同时要做防抖。
一开始是这样写的:
ts
const getRepo = useCallback(
debounce((val) => {
SetRepo([]);
new Octokit()
.request("GET /search/repositories", {
q: val,
per_page: 50,
headers: {
"X-GitHub-Api-Version": "2022-11-28",
},
})
.then((res) => {
SetRepo(res.data.items as Repo[]);
});
}, 1000),
[]
);
useEffect(() => getRepo(inputval), [getRepo, inputval]);
ESLint就报警告了:
WARNING
React Hook useCallback received a function whose dependencies are unknown. Pass an inline function instead.eslint(react-hooks/exhaustive-deps)
意思就是说useCallback希望你在里面写内联函数,你把debounce写给它是不够的,ESLint就无法确定他们的依赖关系。
那就写成内联吧,这样?
ts
const getRepo = useCallback(
(inputval:string) =>
debounce((inputval) => {
SetRepo([]);
new Octokit()
.request("GET /search/repositories", {
q: inputval,
per_page: 50,
headers: {
"X-GitHub-Api-Version": "2022-11-28",
},
})
.then((res) => {
SetRepo(res.data.items as Repo[]);
});
}, 1000)(inputval),
[]
);
useEffect(() => getRepo(inputval), [getRepo, inputval]);
但是这样就不对了呀,inputval的改变导致getRepo重新生成,getRepo每次都是一个新的函数,防抖做了个寂寞。
useCallback内联就不能放参数了,如果把debounce看作一个值,只有在依赖项发生变化时才需要重新计算,那是不是还有个useMemo是不是可以用?
那再改一下:
ts
const getRepo = useMemo(
() =>
debounce((val) => {
SetRepo([]);
new Octokit()
.request("GET /search/repositories", {
q: val,
per_page: 50,
headers: {
"X-GitHub-Api-Version": "2022-11-28",
},
})
.then((res) => {
SetRepo(res.data.items as Repo[]);
});
}, 1000),
[]
);
useEffect(() => getRepo(inputval), [getRepo, inputval]);
问题解决,再去github上面搜一下发现也有人遇到这个问题:https://github.com/facebook/react/issues/19240
这就是useMemo好用的地方了。