GraphQL+Next.js环境下Saleor购物车偶尔显示旧版或错误内容
购物车GraphQL数据不一致问题(Saleor + Stepzen + Apollo Client)
问题现象
- 基于Saleor购物车GraphQL + Stepzen合并Strapi GraphQL的方案,90%场景下正常运行,但偶尔出现添加商品后购物车显示旧数据的情况:比如连续4次添加都能正确更新,第5次却回退到之前的购物车状态
- 多次刷新页面时,购物车内容会反复切换不同的历史状态
- 正常加载购物车时有短暂延迟,异常时则瞬间完成加载,推测异常时未等待Saleor的响应
- 执行
saleorcheckoutLinesAddmutation后返回的购物车内容是正确的(包含新添加的商品),但购物车页面通过saleorcheckout查询获取的内容却显示旧数据,需刷新后才能恢复正常
相关代码实现
React购物车查询组件(使用Apollo Hooks)
const Cart = () => { const [token] = useCookies('["token"]') const { data, loading, error } = useCheckoutFetchByTokenQuery({ variables: { checkoutToken: token.token }, skip: !token.token, }); const [CheckoutremoveProduct] = useCheckoutRemoveProductMutation(); if (loading) return <div>Loading...</div>; if (error) return <div>Error</div>; if (!data || !data.saleorcheckout) return null; const products = data.saleorcheckout?.lines || []; return ( <Layout title="Cart"> ..... </Layout> ); }
CheckoutFetchByToken 查询语句
query CheckoutFetchByToken($checkoutToken: saleorUUID!) { saleorcheckout(token: $checkoutToken) { id email lines { id quantity totalPrice { gross { amount currency } } variant { id product { id name slug thumbnail { url alt } cmsContent { SaleorID Title Featured_image { data { attributes { url width height alternativeText } } } } } pricing { price { gross { amount currency } } } name } } totalPrice { gross { amount currency } } } }
ProductAddVariantToCart Mutation语句
mutation ProductAddVariantToCart($checkoutToken: saleorUUID!, $variantId: ID!) { saleorcheckoutLinesAdd( token: $checkoutToken lines: [{ quantity: 1, variantId: $variantId }] ) { checkout { id lines { id quantity variant { id name product { name } } } } errors { message } } }
已尝试的解决方法及未解决的问题
之前遇到过Apollo缓存合并错误(提示saleorProductVariant缺少ID),在查询中添加variant ID后该错误消失,但购物车数据不一致的问题仍存在。
尝试通过配置Apollo Client的typePolicies来处理购物车数据的合并逻辑,但配置未生效(merge函数中的console.log从未触发),当前配置代码如下:
const client = new ApolloClient({ uri: "https://my-stepzen-graphql-url.com/__graphql", cache: new InMemoryCache({ typePolicies: { Query: { fields: { saleorcheckoutLinesAdd: { lines: { merge(existing, incoming, { mergeObjects }) { console.log(existing) console.log(incoming) return mergeObjects(existing, incoming); }, }, }, }, }, }, }), })
内容的提问来源于stack exchange,提问作者Laurence Cope
相关产品推荐
相关产品推荐

