阿波罗(Apollo):Push()方法导致组件在Mutation中的optimisticResponse更新时卸载

时间:2018-12-11 13:20:15

标签: reactjs graphql apollo apollo-client

任何人都可以猜测以下乐观响应/更新代码的原因吗(问题在代码后继续出现):

AddToCart.js

const ADD_TO_CART_MUTATION = gql`
  mutation addToCart($id: ID!) {
    addToCart(id: $id) {
      id
      quantity
    }
  }
`;

class AddToCart extends React.Component {
  outOfStock(){
    alert('This item is out of stock.');
  };
  
  update = (cache, { data: { addToCart } }) => {
    const data = cache.readQuery({ query: CURRENT_USER_QUERY });
    data.me.cart.push(addToCart);
    cache.writeQuery({ query: CURRENT_USER_QUERY, data });
  };
  
  render() {
    const { id, quantity, title, image, price } = this.props;
    return (
      <Mutation
        mutation={ADD_TO_CART_MUTATION}
        variables={{
          id,
        }}
        optimisticResponse={{
          __typename: 'Mutation',
          addToCart: {
            __typename: 'CartItem',
            id: '-1',
            quantity: 1,
            item: {
              __typename: 'Item',
              id,
              price,
              image,
              title,
              description: 'test',
              mainDescription: 'test',
              quantity,
            }
          }
        }}
        update={this.update}
        refetchQueries={[{ query: CURRENT_USER_QUERY }, { query: ALL_ITEMS_QUERY }]}
      >
        {(addToCart, { loading }) => {
          if (quantity >= 1) {
            return (<button disabled={loading} onClick={() => {
              addToCart().catch(err => alert(err.message));
            }}>
              Add{loading && 'ing'} To Cart 
            </button>)
          } else {
            return (<button>
              Out of Stock 
            </button>)
          }
        }}
      </Mutation>
    );
  }
}

export default AddToCart;

AddToCart父组件(Item.js)

export default class Item extends Component {
  static propTypes = {
    item: PropTypes.object.isRequired,
  };

  render() {
    const { item } = this.props;
    return (
      <User>
        {({ data: { me } }) => {
          let hasPerms;
          hasPerms = (me && me === null) ? false : (me && me.permissions.some(permission => ['ADMIN'].includes(permission)));
          return (
          <ItemStyles>
            {item.image && <img src={item.image} alt={item.title} />}
            <Title>
              <Link
                href={{
                  pathname: '/item',
                  query: { id: item.id },
                }}
              >
                <a>{item.title}</a>
              </Link>
            </Title>
            <PriceTag>{formatMoney(item.price)}</PriceTag>
            <p>{item.description} { (item.quantity <= 10 && item.quantity !== 0) && `- (${item.quantity} in stock)` }</p>
            <div className="buttonList">
              <AddToCart id={item.id} quantity={item.quantity} image={item.image} title={item.title} price={item.price} />
              {hasPerms && (
              <>
              <Link
                href={{
                  pathname: 'update',
                  query: { id: item.id },
                }}
              >
                <a>Edit ✏️</a>
              </Link>
              <DeleteItem id={item.id}>Delete This Item</DeleteItem>
              </>
              )}
            </div>
            <div className="buttonList">
            </div>
          </ItemStyles>
          );
        }}
      </User>
    );
  }
}

项目父项(Items.js)

class Items extends Component {
  render() {
    return (
      <Center>
        <Pagination page={this.props.page} />
        <Query
          query={ALL_ITEMS_QUERY}
          variables={{
            skip: this.props.page * perPage - perPage,
          }}
        >
          {({ data, error, loading }) => {
            if (loading) return <p>Loading...</p>;
            if (error) return <p>Error: {error.message}</p>;
            return (
              <ItemsList>{data.items.map((item, i) => <Item item={item} key={item.id}></Item>)}</ItemsList>
            );
          }}
        </Query>
        <Pagination page={this.props.page} />
      </Center>
    );
  }
}

export default Items;

在将商品添加到空购物车后,导致我的UI重新呈现(组件卸下)(请参见复制说明)?

  1. 转到https://flamingo-next-production.herokuapp.com
  2. 使用登录名,用户名:testing123@123.com,密码:testing123
  3. 点击“我的购物车”链接,然后删除其中的所有物品。让购物车窗口保持打开状态。
  4. 单击Shop链接并添加一个项目。单击添加后,请观察打开的购物车窗口/ UI(您可能需要稍等片刻才能观察到更改)。

为什么会发生这种情况?纠正它的最佳方法是什么?

0 个答案:

没有答案