React Hooks:使用 isFetching 防止 useEffect 中并发 GET 请求

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

我目前正在 React 中开发一个功能,我需要在每次更改

mapState.bounds
时执行 GET 请求,这是我使用 Redux 的 useSelector 从功能切片中提取的值。这是我当前实现的简化版本:

const mapState = useSelector(selectMapState); 
const [searchFoo, { data, isFetching }] = useLazyGetFooSearchQuery();

const fetchData = React.useCallback(async (searchQuery: string) => {
    const { isError, error } = await searchFoo({ query: searchQuery });

    if (isError) {
        console.error(error);
    }
}, [searchFoo]);
    
React.useEffect(() => {
    /*
        Abort if already fetching to prevent 
        executing concurrent GET queries
    */
    if (isFetching) return;

    const searchQuery = JSON.stringify({/* A query based on mapState.bounds */ });

    fetchData(searchQuery).catch((error) => console.error(error));
}, [
    mapState.bounds,
    /* 
       This causes an infinite loop, but not including it 
       in the dependency array will break the exhaustive deps rule
    */
    isFetching,
    fetchData,
]);

主要目标是避免在 mapState.bounds 快速连续变化时执行并发 GET 查询。当我从 useEffect 的依赖数组中排除 isFetching 时,当前设置确实有效,但这违反了 React 维护详尽依赖数组的准则。将其作为依赖项包含会导致无限循环:

  1. mapState.bounds
    的值发生变化
  2. useEffect
    被解雇了
  3. fetchData
    异步调用
  4. isFetching
    被 redux-toolkit 更改为
    true
  5. useEffect
    被激发,但立即返回
  6. data
    已填充,
    fetchData
    返回 void
  7. isFetching
    更改为
    false
  8. 由于上一步,
  9. useEffect
    再次被触发 - 转到步骤 3

一个可能的解决方案可以是在事件侦听器的回调中执行获取查询,例如 onBoundsChange,但我有兴趣知道是否有一种方法可以使用 React 钩子来实现它,同时将钩子中使用的所有变量保留在依赖项数组中,如下所示官方推荐。

如何利用 React hooks 来防止并发 GET 查询,同时遵守详尽的依赖规则?

reactjs asynchronous react-hooks redux-toolkit
© www.soinside.com 2019 - 2024. All rights reserved.