阿波罗客户端 3 缓存在突变后不更新



首先,如果这是重复的,我想道歉,但类似问题的现有答案都没有帮助我。

我使用的是nextjs 9.5.3和apollo客户端3.2.2。我有一个表单,用户可以填写它来更新他们的配置文件详细信息。提交时,保存的数据将保存在数据库中,并将响应返回给客户端。问题是响应无法更新缓存,但根据apollo devtools,它可以在ROOT_MUTATION中找到。

我使用一个查询最初加载用户的数据,然后在突变过程中用结果更新缓存。以下是本地查询和突变。

// fragments

export const editUserProfileFragment= gql`
fragment EditUserProfileFields on ProfileInterface {
id
type
slug
name
location {
name
address
country
latitude
longitude
}
settings
createdAt
isActive
}
`;
// query
export const editUserProfileQuery = gql`
query EditUserProfile($slug: String) {
Profile(slug: $slug) {
...EditUserProfileFields
}
}
${editUserProfileFragment}
`;
// mutation
export const editUserProfileMutation = gql`
mutation EditUserProfile($id: ObjectID!, $profile: ProfileInput!) {
editProfile(id: $id, profile: $profile) {
...EditUserProfileFields
}
}
${editUserProfileFragment}
`;

以下是我如何使用查询和突变:

// the query
const { error, data, loading } = useQuery(editUserProfileQuery, {
variables: { slug },
fetchPolicy: "network-only",
})
// data returns a `Profile` object
// the mutation
const [editUserProfileMutate] = useMutation(editUserProfileMutation)
...
// save data
try {
const response = await editUserProfileMutate({
variables: { id, profile: inputdata },
// update: (cache, { data }) => {
//   const cachedData: any = cache.readQuery({
//     query: editUserProfileQuery,
//     variables: { slug: newProfile.slug }
//   });
//   const cacheId = cache.identify(data.editProfile) // to see the id, i wanted to try cache.modify() but didn't how to proceed.
//   console.log('update.cachedData', cachedData);
//   console.log('update.cachedData.Profile', cachedData.Profile);
//   console.log('update.data', data);
//   const newData = { ...cachedData.Profile, ...data.editProfile }; // i first used [] but 
//   console.log('newData', newData);

//   // cache.writeQuery({
//   //   query: editUserProfileQuery,
//   //   variables: { slug: newProfile.slug },
//   //   data: { editProfile: newData }
//   // })
//   // cache.modify({
//   //   id: cacheId,
//   // })
// },
// tried the below but didn't work
// refetchQueries: [{
//  query: editProfilePageQuery,
//  variables: { slug: newProfile.slug },
// }],
// awaitRefetchQueries: true
});
const updatedProfile = response.data.editProfile;
console.log('updatedProfile', updatedProfile);
....
} catch (error) {
....
} // trycatch

此外,下面的apollo客户端主要基于nextjs和apollo示例:

...
let apolloClient;
...
const cache = new InMemoryCache({
// https://www.apollographql.com/docs/react/data/fragments/#using-fragments-with-unions-and-interfaces
dataIdFromObject: result => `${result.__typename}:${result._id || result.id || result.name || result.slug || Math.floor(Math.random() * 1000000)}`,
possibleTypes: {
ProfileInterface: ["Star", "User"],
},
// @see https://www.apollographql.com/docs/react/caching/cache-field-behavior/#merging-non-normalized-objects from console warnings
typePolicies: 
User: {
fields: {
location: {
merge(_existing, incoming) {
return incoming;
},
},
},
},
},
});

function createClient() {
const link = makeLink();

return new ApolloClient({
cache,
link,
connectToDevTools:typeof window !== 'undefined',
ssrMode: typeof window === 'undefined',
});
}
export function initializeApollo(initialState = null) {
const _apolloClient = apolloClient ?? createClient()
if (initialState) {
const existingCache = _apolloClient.extract()
console.log('existingCache', existingCache);
// _apolloClient.cache.restore({ ...existingCache, ...initialState }) // commented out on purpose
_apolloClient.cache.restore(initialState)
}
if (typeof window === 'undefined') return _apolloClient
if (!apolloClient) apolloClient = _apolloClient
return _apolloClient
}
export function useApollo(initialState) {
const store = useMemo(() => initializeApollo({ initialState }), [initialState])
return store
}

因此,在查看了后端源代码后,我发现我没有从数据库返回更新的值,而是返回旧值。我把它修好了,它正常工作。

最新更新