通过 compose( graphql() ) 手动触发查询
Posted
技术标签:
【中文标题】通过 compose( graphql() ) 手动触发查询【英文标题】:Manually fire a query via compose( graphql() ) 【发布时间】:2019-11-03 01:58:15 【问题描述】:我是 Apollo 和 graphql 的新手,我正在尝试使用 shopify 的店面 API 设置一个电子商务网站。该网站是用 react 和 Next.js 构建的,用于 s-s-r。
我已经设法获得了一些样板代码,用于与 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 时,我们如何将变量动态传递给查询? 为什么我从这个查询中得到错误,而不是突变,在运行之前也需要变量?【问题讨论】:
【参考方案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 客户端手动触发查询。 哦,哇,您刚刚编辑并回答了我的评论。谢谢 :)。不过后续问题:如果我跳过它,我是否可以使用变量手动触发它? 啊,我明白了。以及如何从子组件手动访问客户端?以上是关于通过 compose( graphql() ) 手动触发查询的主要内容,如果未能解决你的问题,请参考以下文章
如何将两个依赖的 GraphQL 查询与“compose”结合起来?
hasura graphql-engine &&patroni docker-compose 环境运行
如何测试graphql apollo组件?如何在 compose() 中获得完整的覆盖?