reactjs - Apollo:Push() 方法导致组件在 Mutation 中的乐观响应更新时卸载
问题描述
任何人都可以猜测以下乐观响应/更新代码的原因(代码后问题继续存在):
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 重新呈现(组件卸载)(请参阅复制说明)?
- 转到https://flamingo-next-production.herokuapp.com。
- 登录使用,用户名:
testing123@123.com
,密码:testing123
。 - 单击“我的购物车”链接并删除其中的所有项目。保持购物车窗口打开。
- 单击
Shop
链接并添加一个项目。单击添加后观察打开的购物车窗口/UI(您可能需要等待片刻才能观察到变化)。
为什么会发生这种情况以及纠正它的最佳方法是什么?
解决方案
推荐阅读
- reactjs - React Spinbutton 小部件不会检测到 aria-labels
- json - 在grafana中使用正则表达式从字符串字段中提取值
- c - 了解 C 中的位级浮点乘法?
- java - Json 模式验证失败并出现 MalformedURLException:未知协议:类路径错误
- c++ - 在旧版本的 gcc 上编译 C++11 代码
- python - 为什么不在 RandomizedSearchCV 中评估过度测试拟合结果?
- sql-server - SQL Server Profiler 忽略大查询
- ios - 未调用 didFinishLaunchingWithOptions 时的条件?
- java - DSE Graph 随机连接关闭异常
- javascript - 如何不使用 log4js 覆盖当前的 DateFile