【问题标题】:Manually fire a query via compose( graphql() )通过 compose( graphql() ) 手动触发查询
【发布时间】:2019-11-03 01:58:15
【问题描述】:

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

我已经设法获得了一些样板代码,用于与 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。如果有,我将加载该结帐。现在结帐是在页面组件中创建的:

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”,但这不会导致错误。我注意到的另一件事是突变作为函数添加到组件道具中,而我的查询被添加为对象。

我正在努力寻找任何好的文档。

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

【问题讨论】:

    标签: reactjs graphql apollo react-apollo


    【解决方案1】:

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

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

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

    选项配置的文档是here

    您还可以通过在以下选项下添加跳过检查来跳过自动触发查询

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

    【讨论】:

    • 谢谢约翰尼,但如果这是用户第一次访问怎么办。那么localstorage中还没有checkoutID。我需要能够首先检查它,可能在 componentWillMount 钩子中。是否可以推迟触发查询,直到从 component.props 调用它?
    • 我,编辑了答案。如果你想要类似于突变的东西,那么你将不得不使用 apollo 客户端手动触发查询。
    • 哦,哇,您刚刚编辑并回答了我的评论。谢谢 :)。不过后续问题:如果我跳过它,我是否可以使用变量手动触发它?
    • 啊,我明白了。以及如何从子组件手动访问客户端? 的子级
    • 你能在这里加入聊天吗chat.stackoverflow.com/rooms/195256/gql
    猜你喜欢
    • 2017-08-27
    • 2022-11-16
    • 1970-01-01
    • 2017-07-20
    • 2020-01-20
    • 2019-12-06
    • 2020-05-21
    • 2014-09-29
    • 2021-07-20
    相关资源
    最近更新 更多