通过compose(graphql())手动触发查询

时间:2019-06-20 09:15:33

标签: reactjs graphql apollo react-apollo

我是Apollo和graphql的新手,我正在尝试使用shopify的店面API建立一个电子商务网站。该网站是使用react和用于SSR的Next.js构建的。

我设法获得一些样板代码,用于与shopify进行基本的购物车互动。我有一个包装整个应用程序的Page组件,它位于ApolloProvider下面,可以访问apollo客户端。目前,我正在使用compose()为我的Page组件提供一些graphql(taken from this example):

const pageWithData = compose(
  graphql(query), // Query that retrieves base shopify information, such as shop name, description and products
  graphql(createCheckout, {name: "createCheckout"}), // Mutation that creates a new checkout object with shopify. Basically a cart object
  graphql(checkoutLineItemsAdd, {name: "checkoutLineItemsAdd"}), // Mutation that adds a new lineitem to the checkout object
  graphql(checkoutLineItemsUpdate, {name: "checkoutLineItemsUpdate"}), // Mutation that updates a line item
  graphql(checkoutLineItemsRemove, {name: "checkoutLineItemsRemove"}), // Mutation that removes a lineitem
)(Page);

这一切都按预期工作,除非我刷新浏览器,否则将清空购物车,并创建一个新的结帐对象。因此,我想做的是将签出ID存储在localStorage中,并在创建新的签出对象之前检查localstorage中是否有ID。如果有一个,我将改为加载该结帐。现在,就像在Page组件中一样创建了结帐:

componentWillMount() {
    this.props.createCheckout({
        variables: {
            input: {}
        }}).then((res) => {
        this.setState({
            checkout: res.data.checkoutCreate.checkout
        });
    });
}

现在,我发现了一个可运行的graphql查询,用于基于ID加载现有的结帐:

const checkoutFetchQuery = gql`
  query checkoutFetch ($checkoutId: ID!) {
      node(id: $checkoutId) {
        ... on Checkout {
          webUrl
          subtotalPrice
          totalTax
          totalPrice
          lineItems (first:250) {
            pageInfo {
              hasNextPage
              hasPreviousPage
            }
            edges {
              node {
                title
                variant {
                  title
                  image {
                    src
                  }
                  price
                }
                quantity
              }
            }
          }
        }
      }
    }
`;

所以我想我可以将其简单地添加到这样的compose方法中:

const pageWithData = compose(
  graphql(query), // Query that retrieves base shopify information, such as shop name, description and products

  graphql(checkoutFetchQuery, { name: "fetchCheckout"}), // Query that fetches checkout based on a checkoutID

  graphql(createCheckout, {name: "createCheckout"}), // Mutation that creates a new checkout object with shopify. Basically a cart object
  graphql(checkoutLineItemsAdd, {name: "checkoutLineItemsAdd"}), // Mutation that adds a new lineitem to the checkout object
  graphql(checkoutLineItemsUpdate, {name: "checkoutLineItemsUpdate"}), // Mutation that updates a line item
  graphql(checkoutLineItemsRemove, {name: "checkoutLineItemsRemove"}), // Mutation that removes a lineitem
)(Page);

但这会导致Apollo开发工具出现以下错误:

GraphQL Errors: Variable checkoutId of type ID! was provided invalid value

我敢肯定,这是我不了解compose()如何在react-apollo中工作的一些关键概念。我知道我需要给查询提供一些变量,但是由于某种原因,该查询似乎在加载时立即运行,正如我期望的那样,这只会使查询在组件上可用。其他一些graphql()语句也需要变量,例如“ checkoutLineItemsAdd”,但这不会导致错误。我注意到的另一件事是,将突变作为函数添加到组件props中,在此,我的查询作为对象添加了。

我正在努力寻找与此相关的任何文档。

  • 查询是否立即运行?
  • 是否正在等待从组件调用突变,从而允许我们动态添加变量?
  • 我应该以不同的方式编写我的gql语法,使其成为组件上的函数而不是对象上的函数吗?
  • 当附加到撰写HOC时,如何将变量动态传递给查询?
  • 如何从此查询中得到错误,而不是突变,在运行前也需要变量?

1 个答案:

答案 0 :(得分:1)

您的查询需要输入checkoutId,其类型为ID

但是您的查询graphql(checkoutFetchQuery, { name: "fetchCheckout"})被激发而没有任何输入。您可以这样做添加输入变量

graphql(checkoutFetchQuery, {
  name: "fetchCheckout",
  options: {
    variables: {
      checkoutId: localstorage.get('checkoutid')
    }
  }
})

选项配置的文档为here

您还可以通过在诸如以下的选项下添加跳过检查来跳过自动启动查询

options: {
  skip: !localstorage.get('checkoutid')
}