我只从 lodash 导入去抖功能:
import debounce from "lodash/debounce"
我希望消除抖动的函数是一个名为“fetchUsers”的异步函数。所以我正在创建函数的去抖动版本:
const debouncedFetchUsers = debounce(fetchUsers, 5000)
当 inputValue 改变时,这会从 useEffect 调用:
useEffect(() => {
if (inputValue.length > 2) {
debouncedFetchUsers(inputValue);
} else {
setUsers([]);
}
}, [inputValue, debouncedFetchUsers]);
如果我在 inputValue 文本字段中快速连续键入 5 个字符,fetchUsers 函数将被调用(使用正确的
inputValue
)3 次....在每个字符按下延迟 5 秒后。
值得注意的是,如果我在我的 useEffect 依赖项数组中包含
debouncedFetchUsers
,我会得到一个无限的重新渲染循环。这让我觉得每次渲染都会重新创建函数。
这让我得到了 Lodash 在 react 中去抖动的答案 所以我将我的
debouncedFetchUsers
包装在一个 useCallback 中,因此:
const debouncedFetchUsers = useCallback(
debounce(fetchUsers, 5000),
[fetchUsers]
);
这不能解决无限 useEffect 循环。
所以,我跟进链并将
fetchUsers
包装在useCallback中。这解决了问题。
为了完整性,这是
fetchUsers
功能:
const fetchUsers = useCallback(async (needle) => {
console.log(`FetchingUsers...${needle}`);
setIsLoading(true);
const response = await fetch(`http://localhost:7000/users?needle=${needle}`);
const data = await response.json();
setUsers(data);
setIsLoading(false);
console.log(`DONE FetchingUsers...${needle}`);
}, []);
.
始终确保正确填充依赖项数组。您为 ESlint 配置了正确的反应钩子规则,例如详尽的依赖规则,以使所有依赖关系正确。
您可能需要在 useCallback 中将 fetchUsers 函数作为依赖项传递,如下所示:
const debouncedFetchUsers = useCallback(
debounce(fetchUsers, 5000),
[fetchUsers]
);
如果你想避免这种情况你可以直接在使用回调中写函数逻辑:
const debouncedFetchUsers = useCallback(
debounce(() => {
// your function logic here
}, 5000),
[]
);
此外,useEffect 应该将记忆回调作为依赖项:
useEffect(() => {
if (inputValue.length > 2) {
debouncedFetchUsers();
} else {
setUsers([]);
}
}, [inputValue, debouncedFetchUsers]);
看看这是否有效