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

Reactjs 通过compose(graphql())手动触发查询,reactjs,graphql,apollo,react-apollo,Reactjs,Graphql,Apollo,React Apollo,我是Apollo和graphql的新手,我正在尝试用shopify的店面API建立一个电子商务网站。该网站是用react和Next.js为SSR构建的 我已经设法获得了一些样板代码,用于与shopify的基本购物车交互。我有一个包装整个应用程序的页面组件,它位于apollo提供商下方,可以访问apollo客户端。目前,我正在使用compose()为页面组件提供一些graphql(): 除了刷新浏览器、清空购物车和创建新的签出对象外,所有这些都按预期工作。因此,我要做的是在创建新的签出对象之前,将

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

我已经设法获得了一些样板代码,用于与shopify的基本购物车交互。我有一个包装整个应用程序的页面组件,它位于apollo提供商下方,可以访问apollo客户端。目前,我正在使用compose()为页面组件提供一些graphql():

除了刷新浏览器、清空购物车和创建新的签出对象外,所有这些都按预期工作。因此,我要做的是在创建新的签出对象之前,将签出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);
但这导致阿波罗开发工具出现以下错误:

GraphQL Errors: Variable checkoutId of type ID! was provided invalid value
我确信这是我不理解compose()在阿波罗中如何工作的一些关键概念。我知道我需要向查询提供一些变量,但出于某种原因,该查询似乎在加载时立即运行,正如我所预期的那样,这将使查询在组件上可用。其他一些graphql()语句也需要变量,例如“checkoutLineItemsAdd”,但这不会导致错误。我注意到的另一件事是,突变作为函数添加到组件道具中,其中作为我的查询作为对象添加

我很难找到关于这方面的好文件

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

但是您的查询
graphql(checkoutFetchQuery,{name:“fetchCheckout”})
在没有任何输入的情况下被激发。这样可以添加输入变量

graphql(checkoutFetchQuery, {
  name: "fetchCheckout",
  options: {
    variables: {
      checkoutId: localstorage.get('checkoutid')
    }
  }
})
选项配置的文档是

您还可以通过在选项(如)下添加跳过检查,从自动触发中跳过查询

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

谢谢Johnny,但是如果这是用户的第一次访问呢。那么本地存储中就不会有签出ID了。我需要能够首先检查它,可能在组件Willmount hook中。是否可以推迟触发查询,直到从组件调用查询。props?Ive编辑了答案。如果你想要类似突变的东西,那么你必须使用apollo客户端手动启动查询。哇,你刚刚编辑并回答了我的评论。谢谢:)。但接下来的问题是:如果我跳过它,我能用变量手动启动它吗?啊,我明白了。如何从子组件手动访问客户端?是的孩子,你能加入这里的聊天吗
options: {
  skip: !localstorage.get('checkoutid')
}