Apollo和React:refreshQueries无法在onClick()中触发变异

时间:2017-11-19 23:23:07

标签: reactjs graphql apollo

我正在构建一个简单的购物应用。在加载时,我们会进行查询以检查购物车是否存在。目前,该查询始终返回null(我还没有实现逻辑,以检查用户是否已经拥有购物车)。然后,当用户点击"创建购物车"时,我们会做一个变异来创建它。最后,我们将在突变完成后使用refreshQueries来通过ID获取购物车(及其产品),ID从突变中返回。然后,我们将这些产品呈现为纯粹的组件。

我遇到的问题是,在用户点击按钮并发生refreshQueries后,没有任何内容重新呈现。我知道正在发送查询并通过查看我的开发人员工具返回创建的带有产品的购物车。网络标签。只是阿波罗似乎没有注意到这种变化。

Mongo是我的后端。

以下是相关代码:

// query
import { gql } from 'react-apollo';

export const cartQuery = gql`
  query CartQuery($cartId: ID) {
    cart(cartId: $cartId) {
      _id,
      products {
        _id,
        name
      }
    }
  }
`;

// mutation
import { gql } from 'react-apollo';

export const createCartMutation = gql`
  mutation CreateCartMutation {
    createCart {
      _id
    }
  }
`;

// Apollo + React stuff
import React from 'react';
import { graphql } from 'react-apollo';

import { createCartMutation } from '../../mutations';
import { cartQuery } from '../../queries';

const BuildCart = ({ mutate }) => (
  <button
    onClick={() => {
      // even when I hardcode the ID of a cart that exists and contains products, it doesn't matter
      mutate({
        refetchQueries: [{ query: cartQuery, variables: { cartId: '12345abcd' } }],
      });
    }}
  >
    Click
  </button>
);

const BuildCartConnected = graphql(createCartMutation)(BuildCart);

const Cart = ({ data, data: { cart, loading } }) => {
  console.log(cart); // always null, even after clicking button
  return (
    <div>
      <BuildCartConnected />
      {loading && <p>Loading...</p>}
      // never gets to this step, even though the response is a properly formed cart with an array of products
      {cart && cart.products.map(product => (
        <p key={Math.random()}>{product.name}</p>
      ))}
    </div>
  );
};

const CartConnected = graphql(cartQuery)(Cart);

export default CartConnected;

如果它有用,请点击网络标签中refetchQueries的响应: {"data":{"cart":{"_id":"12345abcd","products":[{"_id":"abcdef12345","name":"Product A","__typename":"Product"}],"__typename":"Cart"}}}

1 个答案:

答案 0 :(得分:0)

您的cart查询需要cartId个变量。在上面的代码中,您没有提供该变量,因此其值未定义。 Apollo将查询和变量的组合与您的Cart组件相关联。

当您使用与提供给HOC的不同的变量调用refetch查询时,将获取该新查询的结果并将其保留在商店中。但是,就Apollo所知,您仍然希望将未定义的查询结果作为该组件的变量值,而不是您获取它的新结果。

refetchQueries不应该用于您尝试做的事情。相反,cart查询的变量应该来自props:

const options = ({cartId}) => ({variables: {cartId}})
const CartConnected = graphql(cartQuery, {options})(Cart)

然后,当您调用mutate时,它会返回一个Promise,它将解析为突变返回的数据。我们可以从响应中获取cartId并将其存储在应用程序状态中(通过调用setState,启动Redux操作等)。然后,您可以将该状态作为道具传递到Cart组件。更新状态时,prop会更改并获取带有新提供的变量的查询。