【问题标题】:How to fetch multiple conditional queries in Apollo Client React?如何在 Apollo Client React 中获取多个条件查询?
【发布时间】:2020-03-14 10:42:25
【问题描述】:

我正在使用 Apollo 客户端,为了获取查询,我正在使用来自包 @apollo/react-hooksuseQuery

我想完成以下工作:

步骤列表:

第 1 步:获取查询 stage

const GetStage = useQuery(confirmStageQuery, {
  variables: {
    input: {
      id: getId.id
    }
  }
});

第 2 步:根据我们从 GetStage 获得的回复,我们希望在 2 个单独的查询之间切换

if (!GetStage.loading && GetStage.data.getGame.stage === "Created") {
  Details = useQuery(Query1, {
    variables: {
      input: {
        id: getId.id
      }
    }
  });
} else if (!GetStage.loading && GetStage.data.getGame.stage === "Confirmed") {
  Details = useQuery(Query2, {
    variables: {
      input: {
        id: getId.id
      }
    }
  });
}

第 3 步:此外,每次页面加载时,我都会重新获取数据。

useEffect(() => {
  //Fetch for Change in the Stage
  GetStage.refetch();

  //Fetch for Change in the Object
  if (Details) {
    Details.refetch();
    if (Details.data) {
      setDetails(Details.data.getGame);
    }
  }
});

有问题?

比上一次渲染时渲染了更多的钩子。

Details.data 未定义

那么我们如何在 Apollo Client 中调用多个异步查询呢?

【问题讨论】:

    标签: javascript asynchronous react-hooks react-apollo apollo-client


    【解决方案1】:

    正如菲利普所说,你不能有条件地调用钩子。然而,有条件地调用查询非常常见,因此 Apollo 允许您使用 skip 选项跳过它:

    const { loading, error, data: { forum } = {}, subscribeToMore } = useQuery(GET_FORUM, {
      skip: !forumId,
      fetchPolicy: 'cache-and-network',
      variables: { id: forumId },
    });
    

    调用了钩子,但没有调用查询。在我看来,这比在你的用例中使用惰性查询更简单、更清晰。

    【讨论】:

    • 这是一个好方法,但是当你想获取第一个或第二个查询时,延迟钩子是解决这个问题的最佳方法,在我看来。
    【解决方案2】:

    The rules of hooks 说你不能有条件地调用钩子,每当你发现自己处于想在钩子周围使用 if/else 的情况下,你可能走错了路。

    您在此处要做的是将lazyQuery 用于“可选”或稍后将被提取的所有内容 - 或用于依赖于另一个查询结果的查询。

    这是一个简单的示例(可能还不够完整,无法让您的整个代码正常工作):

    // This query is always called, use useQuery
    const GetStage = useQuery(confirmStageQuery, {
      variables: {
        input: {
          id: getId.id
        }
      }
    });
    
    const [fetchQuery1, { loading1, data1 }] = useLazyQuery(Query1);
    const [fetchQuery2, { loading2, data2 }] = useLazyQuery(Query2);
    
    // Use an effect to execute the second query when the data of the first one comes in
    
    useEffect(() => {
      if (!GetStage.loading && GetStage.data.getGame.stage === "Created") {
        fetchQuery1({variables: {
         input: {
            id: getId.id
          }
        }})
      } else if (!GetStage.loading && GetStage.data.getGame.stage === "Confirmed") {
        fetchQuery2({variables: {
         input: {
            id: getId.id
          }
        }})
      } 
    }, [GetState.data, GetStage.loading])
    

    【讨论】:

      猜你喜欢
      • 2018-03-04
      • 2022-01-09
      • 1970-01-01
      • 2017-11-10
      • 2017-03-10
      • 2017-09-08
      • 2018-07-17
      • 2021-08-02
      • 2021-10-08
      相关资源
      最近更新 更多