使用 React 查询:当 setStart 和 setSearch (useState) 同时更改时,查询发送两次。 (搜索和开始是查询参数)

问题描述 投票:0回答:1

问题是:如果我同时更改开始和搜索,则会发送两个查询,但我只想要一个。

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)
    });

有更好的方法吗?

reactjs tanstackreact-query
1个回答
0
投票

在我看来,这是避免快速连续触发多个查询的好方法。

还可以通过利用像 React Query 的 useQuery hook 这样的库来优化,它本身支持 staleTime 选项或重新获取触发器。

如果仍然需要去抖,请考虑使用更简单的方法,无需自定义挂钩或集成更专业的去抖库,如 lodash。

无需自定义去抖逻辑的可能改进可能是:

  1. 使用 Lodash 去抖动 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
});
  1. 完善去抖策略 另一种方法是确保仅对启动和搜索的 setter 函数进行反跳操作,这会稍微提高性能:
const debouncedSetStart = useCallback(debounce(setStart, 500), []);
const debouncedSetSearch = useCallback(debounce(setSearch, 500), []);

例如,这避免了将整个查询包装在去抖动处理程序中的需要,从而允许精确控制状态更新,减少不必要的渲染和查询。

这两种方法都旨在提高可维护性并避免自定义去抖钩子,除非确实需要。

我希望我能有所帮助, K.

© www.soinside.com 2019 - 2024. All rights reserved.