问题是:如果我同时更改开始和搜索,则会发送两个查询,但我只想要一个。
const [start, setStart] = useState(0);
const [search, setSearch] = useState('')
const { data: usersData, error: usersError, isLoading: usersIsLoading, isError: usersIsError } = useQuery({
queryKey: ['users', start, search],
queryFn: () => getUsers(start, search)
});
我找到的解决方案是使用去抖动功能:
const [start, setStart] = useState(0);
const [search, setSearch] = useState('');
const debouncedStart = useValueDebounce(start, 500);
const debouncedSearch = useValueDebounce(search, 500);
function useValueDebounce(value, delay) {
const [debouncedValue, setDebouncedValue] = useState(value);
useEffect(() => {
const handler = setTimeout(() => {
setDebouncedValue(value);
}, delay);
return () => {
clearTimeout(handler);
};
}, [value, delay]);
return debouncedValue;
}
const { data: usersData, error: usersError, isLoading: usersIsLoading, isError: usersIsError } = useQuery({
queryKey: ['users', debouncedStart, debouncedSearch],
queryFn: () => getUsers(limit, debouncedStart, debouncedSearch)
});
有更好的方法吗?
在我看来,这是避免快速连续触发多个查询的好方法。
还可以通过利用像 React Query 的 useQuery hook 这样的库来优化,它本身支持 staleTime 选项或重新获取触发器。
如果仍然需要去抖,请考虑使用更简单的方法,无需自定义挂钩或集成更专业的去抖库,如 lodash。
无需自定义去抖逻辑的可能改进可能是:
import { debounce } from 'lodash';
import { useQuery } from 'react-query';
const [start, setStart] = useState(0);
const [search, setSearch] = useState('');
const fetchUsers = useCallback(debounce((start, search) => getUsers(start, search), 500), []);
const { data: usersData, error: usersError, isLoading: usersIsLoading, isError: usersIsError } = useQuery({
queryKey: ['users', start, search],
queryFn: () => fetchUsers(start, search),
staleTime: 500 // Optional: time to consider data fresh, avoids refetching
});
const debouncedSetStart = useCallback(debounce(setStart, 500), []);
const debouncedSetSearch = useCallback(debounce(setSearch, 500), []);
例如,这避免了将整个查询包装在去抖动处理程序中的需要,从而允许精确控制状态更新,减少不必要的渲染和查询。
这两种方法都旨在提高可维护性并避免自定义去抖钩子,除非确实需要。
我希望我能有所帮助, K.