如何覆盖Apollo缓存中的值?
我有一个graphql查询来获取用户。这将返回具有默认币种的用户。然后可以从选择下拉列表中覆盖此货币。
查询从API提取image = pygame.image.load("boomerang64.png")
pos = (200, 200)
angle = 0
while True:
# [...]
rotate_rect, rotate_image = ???? # rotate around green cross by angle
surf.blit(rotated_image, rotate_rect)
angle += 1
# [...]
,然后使用客户端解析器将paymentCurrencies
数组中的第一项设置为用户paymentCurrencies
currency
当有人从下拉菜单中选择一种货币时,我想用他们选择的任何内容覆盖用户的货币。
到目前为止,我有这样的事情:
query me {
me {
username
currency @client
paymentCurrencies
}
}
我收到以下错误:const onChange = e => {
const { value } = e.target
client.writeData({ user: { currency: value, username, __typename: "User" } })
}
使用Error writing result to store for query:
{"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"GeneratedClientQuery"},"selectionSet":null}]}
Cannot read property 'selections' of null
是正确的方法还是应该使用writeData
之类的东西?
答案 0 :(得分:1)
如其他答案中所述,您可能需要简单的查询和突变设置。 client指令用于扩展您的架构以容纳仅客户端的其他数据。从您的解释看来,您似乎明确希望将此数据与服务器同步。
const ME_QUERY = gql`
query me {
me {
username
currency
paymentCurrencies
}
}
`;
const CURRENCY_MUTATION = gql`
mutation setCurrency($currency: String) {
setCurrency(currency: $currency) {
me {
username
currency
}
}
}
`;
function MyComponent() {
const { data } = useQuery(ME_QUERY);
const [setCurrency] = useMutation(CURRENCY_MUTATION);
const onChange = e => setCurrency({
variables: { currency: e.currentTarget.value },
});
return (
<>
<h2>{data && data.me.currency}</h2>
<select onChange={onChange}>
{/* your dropdown logic */}
</select>
</>
);
}
您明白了。现在,Apollo将自动更新您的缓存。确保您的突变允许查询更新的用户对象。
要使自动更新生效,您的用户需要被缓存识别。您可以通过添加id字段并在查询和突变中都选择它,或者在Apollo Client 2.x中实现一个dataIdFromObject
用户名的__typename === 'User'
函数或使用类型来实现Apollo Client 3.x中的策略。找到docs here。
答案 1 :(得分:1)
writeData
应该用于更改根字段,例如:
{
yourState @client
}
在这种情况下,应使用writeQuery。此外,实际上应该将此逻辑提取为一个(本地)变异,然后可以在组件内部调用该变异。使用writeQuery
时,基本思想是获取现有数据,进行复制,然后根据需要进行转换:
const { me } = client.readQuery({ query: ME_QUERY })
const data = {
me: {
...me,
currency: value,
}
}
client.writeQuery({ query: ME_QUERY, data })
您还可以使用writeFragment
直接修改缓存中对象的单个实例。但是,您需要为此使用对象的缓存键。由于缓存键是从__typename
和id
字段派生的,因此您应该确保查询首先包括一个id字段。无论如何确保可以轻松地更新缓存,这都是一个好习惯(有关更多详细信息,请参见here)。然后您可以执行以下操作:
client.writeFragment({
id: 'User:42',
fragment: gql`
fragment UserCurrency on User {
currency @client
}
`,
data: {
currency: value,
},
})
答案 2 :(得分:0)
这取决于。
对于永久更改(与服务器同步),您应该只使用突变更改用户设置。
要了解会话更改-不要使用用户设置-将此(从记录的用户属性中)复制到全局应用程序状态(redux / mobx或在这种情况下,阿波罗{{3 }}。
在这两种情况下,罕见的问题都是使用更改后的数据更新许多组件。
Redux / mobx自动解决此问题。
Apollo HOC不会重新呈现。
挂钩-部分更新(仅具有useQuery
和useMutation
对的挂钩),其他仅在重新渲染时才会更新。
使用<Query/>
构建的组件会在内部创建一个可观察的组件,然后它们也会被更新。
突变具有update
和refetchQueries
参数。
对于更复杂的用例,还有一个local state。