带有 writeQuery 的 Apollo 客户端突变未触发 UI 更新
Apollo client mutation with writeQuery not triggering UI update
我想创建一个新的卡片对象,我希望它应该在更新后添加到用户界面中。缓存、Apollo Chrome 工具和控制台日志记录反映了更改,但 UI 并非没有手动重新加载。
const [createCard, { loading, error }] = useMutation(CREATE_CARD, {
update(cache, { data: { createCard } }) {
let localData = cache.readQuery({
query: CARDS_QUERY,
variables: { id: deckId }
});
localData.deck.cards = [...localData.deck.cards, createCard];
;
client.writeQuery({
query: CARDS_QUERY,
variables: { id: parseInt(localData.deck.id, 10) },
data: { ...localData }
});
我已将 cache.writeQuery 更改为 client.writeQuery,但这并没有解决问题。
供参考,这是我的查询 运行...
const CARDS_QUERY = gql`
query CardsQuery($id: ID!) {
deck(id: $id) {
id
deckName
user {
id
}
cards {
id
front
back
pictureName
pictureUrl
createdAt
}
}
toggleDeleteSuccess @client
}
`;
好的,最后 运行 进入了一个漫长的 Github thread 讨论他们对同一问题的解决方案。最终对我有用的解决方案是深度克隆数据对象(我个人使用 Lodash cloneDeep),在将变异的数据对象传递给 cache.writeQuery 之后,它最终更新了 UI。最终,考虑到缓存反映了更改,似乎仍然应该有一种方法来触发 UI 更新。
这是后文,请查看我原来的前文问题...
const [createCard, { loading, error }] = useMutation(CREATE_CARD, {
update(cache, { data: { createCard } }) {
const localData = cloneDeep( // Lodash cloneDeep to make a fresh object
cache.readQuery({
query: CARDS_QUERY,
variables: { id: deckId }
})
);
localData.deck.cards = [...localData.deck.cards, createCard]; //Push the mutation to the object
cache.writeQuery({
query: CARDS_QUERY,
variables: { id: localData.deck.id },
data: { ...localData } // Cloning ultimately triggers the UI update since writeQuery now sees a new object.
});
},
});
我在没有 cloneDeep
方法的情况下得到了相同的结果。仅使用传播运算符就解决了我的问题。
const update = (cache, {data}) => {
const queryData = cache.readQuery({query: USER_QUERY})
const cartItemId = data.cartItem.id
queryData.me.cart = queryData.me.cart.filter(v => v.id !== cartItemId)
cache.writeQuery({query: USER_QUERY, data: {...queryData}})
}
希望这对其他人有帮助。
我想创建一个新的卡片对象,我希望它应该在更新后添加到用户界面中。缓存、Apollo Chrome 工具和控制台日志记录反映了更改,但 UI 并非没有手动重新加载。
const [createCard, { loading, error }] = useMutation(CREATE_CARD, {
update(cache, { data: { createCard } }) {
let localData = cache.readQuery({
query: CARDS_QUERY,
variables: { id: deckId }
});
localData.deck.cards = [...localData.deck.cards, createCard];
;
client.writeQuery({
query: CARDS_QUERY,
variables: { id: parseInt(localData.deck.id, 10) },
data: { ...localData }
});
我已将 cache.writeQuery 更改为 client.writeQuery,但这并没有解决问题。
供参考,这是我的查询 运行...
const CARDS_QUERY = gql`
query CardsQuery($id: ID!) {
deck(id: $id) {
id
deckName
user {
id
}
cards {
id
front
back
pictureName
pictureUrl
createdAt
}
}
toggleDeleteSuccess @client
}
`;
好的,最后 运行 进入了一个漫长的 Github thread 讨论他们对同一问题的解决方案。最终对我有用的解决方案是深度克隆数据对象(我个人使用 Lodash cloneDeep),在将变异的数据对象传递给 cache.writeQuery 之后,它最终更新了 UI。最终,考虑到缓存反映了更改,似乎仍然应该有一种方法来触发 UI 更新。
这是后文,请查看我原来的前文问题...
const [createCard, { loading, error }] = useMutation(CREATE_CARD, {
update(cache, { data: { createCard } }) {
const localData = cloneDeep( // Lodash cloneDeep to make a fresh object
cache.readQuery({
query: CARDS_QUERY,
variables: { id: deckId }
})
);
localData.deck.cards = [...localData.deck.cards, createCard]; //Push the mutation to the object
cache.writeQuery({
query: CARDS_QUERY,
variables: { id: localData.deck.id },
data: { ...localData } // Cloning ultimately triggers the UI update since writeQuery now sees a new object.
});
},
});
我在没有 cloneDeep
方法的情况下得到了相同的结果。仅使用传播运算符就解决了我的问题。
const update = (cache, {data}) => {
const queryData = cache.readQuery({query: USER_QUERY})
const cartItemId = data.cartItem.id
queryData.me.cart = queryData.me.cart.filter(v => v.id !== cartItemId)
cache.writeQuery({query: USER_QUERY, data: {...queryData}})
}
希望这对其他人有帮助。