【问题标题】:如何使用 Apollo 客户端按顺序链接两个 GraphQL 查询
【发布时间】:2018-08-25 08:01:16
【问题描述】:

我在前端使用 Apollo Client,在后端使用 Graphcool。有两个查询 firstQuerysecondQuery 我希望在页面打开时按顺序调用它们。示例代码如下(TestPage组件的定义不在此列):

export default compose(
        graphql(firstQuery, {
            name: 'firstQuery'
        }),
        graphql(secondQuery, { 
            name: 'secondQuery' ,
            options: (ownProps) => ({
                variables: {
                   var1: *getValueFromFirstQuery*
                }
            })
        })
)(withRouter(TestPage))

我需要从firstQuery 的结果中得到secondQuery 中的var1。我如何使用 Apollo Client 和 compose 做到这一点?或者有没有其他方法可以做到这一点?提前致谢。

【问题讨论】:

    标签: graphql apollo react-apollo apollo-client graphcool


    【解决方案1】:

    firstQuery 组件添加的道具将可用于它下面(内部)的组件,因此您可以执行以下操作:

    export default compose(
      graphql(firstQuery, {
        name: 'firstQuery'
      }),
      graphql(secondQuery, { 
        name: 'secondQuery',
        skip: ({ firstQuery }) => !firstQuery.data,
        options: ({firstQuery}) => ({
          variables: {
              var1: firstQuery.data.someQuery.someValue
          }
        })
      })
    )(withRouter(TestPage))
    

    请注意,我们使用 skip 跳过第二个查询,除非我们确实有来自第一个查询的数据可以使用。

    使用查询组件

    如果您使用Query 组件,您也可以使用skip 属性,尽管您也可以选择在第一个渲染道具函数中返回其他内容(如null 或加载指示器) :

    <Query query={firstQuery}>
      {({ data: { someQuery: { someValue } = {} } = {} }) => (
        <Query
          query={secondQuery}
          variables={{var1: someValue}}
          skip={someValue === undefined}
        >
          {({ data: secondQueryData }) => (
            // your component here
          )}
    </Query>
    

    使用 useQuery 钩子

    您还可以将skipuseQuery 挂钩:

    const { data: { someQuery: { someValue } = {} } = {} } = useQuery(firstQuery)
    const variables = { var1: someValue }
    const skip = someValue === undefined
    const { data: secondQueryData } = useQuery(secondQuery, { variables, skip })
    

    突变

    与查询不同,突变涉及专门调用函数以触发请求。此函数返回一个 Promise,它将使用突变的结果进行解析。这意味着,在处理突变时,您可以简单地将生成的 Promise 链接起来:

    const [doA] = useMutation(MUTATION_A)
    const [doB] = useMutation(MUTATION_B)
    
    // elsewhere
    const { data: { someValue } } = await doA()
    const { data: { someResult } } = await doB({ variables: { someValue } })
    

    【讨论】:

    • 像魅力一样工作!谢谢丹尼尔。奇怪的是我在任何地方都没有找到这方面的文档。
    • 我不敢相信这是有效的。在其他任何地方都找不到这个
    【解决方案2】:

    对于使用react apollo hooks 的任何人,相同的方法都有效。

    你可以使用两个useQuery钩子并将第一个查询的结果传入第二个的skipoption

    示例代码:

    const AlertToolbar = ({ alertUid }: AlertToolbarProps) => {
      const authenticationToken = useSelectAuthenticationToken()
    
      const { data: data1 } = useQuery<DataResponse>(query, {
        skip: !authenticationToken,
        variables: {
          alertUid,
        },
        context: makeContext(authenticationToken),
      })
    
      const { data: data2, error: error2 } = useQuery<DataResponse2>(query2, {
        skip:
          !authenticationToken ||
          !data1 ||
          !data1.alertOverview ||
          !data1.alertOverview.deviceId,
        variables: {
          deviceId:
            data1 && data1.alertOverview ? data1.alertOverview.deviceId : null,
        },
        context: makeContext(authenticationToken),
      })
    
      if (error2 || !data2 || !data2.deviceById || !data2.deviceById.id) {
        return null
      }
      const { deviceById: device } = data2
      return (
        <Toolbar>
        ...
        // do some stuff here with data12
    

    【讨论】:

      猜你喜欢
      • 2016-08-31
      • 2019-07-26
      • 2019-11-02
      • 2020-06-14
      • 2020-03-31
      • 2018-03-25
      • 1970-01-01
      • 2019-09-27
      • 2020-04-27
      相关资源
      最近更新 更多