-
Notifications
You must be signed in to change notification settings - Fork 2.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Nesting .modify() results in React unmounted warning #7061
Comments
+1 On this one. I'm trying to re-order the results of a paginated connection object which comes from a root query. I've got a fieldPolicy on the query that handles a cursor based, load more pagination. When I go to re-order the items in the cache with writeQuery like I could in AC2, It runs through the fieldPolicy which will append my re-ordered items, not replace them with the new node list. A hacky work-around I'm thinking of trying is adding additional arguments to my query which strictly influence how the fieldPolicy operates since I have access to the args. I'd have a default append nodes mode, but with an additional argument my cache update could replace instead. Doesn't really seem right, but seems to theoretically work... |
@Nickersona you can leave out the Or if you mean it's hard to identify which version of root query field with differing pagination arguments, Ben recommends setting |
@Nickersona You can modify root query fields by omitting the cache.modify({
// This would work, but you can just omit the id to achieve the same effect.
// id: "ROOT_QUERY",
fields: {
paginatedItems(items, details) {
return reorder(items);
},
},
}) Edit: thanks to @lorensr for answering this 10 hours before me—I left this issue open overnight and didn't see his comment this morning when I wrote mine! |
@lorensr A nested call to const [removeReview] = useMutation(REMOVE_REVIEW_MUTATION, {
update: (cache) => {
cache.modify({
fields: {
currentUser(currentUserRef) {
cache.modify({
id: currentUserRef.__ref,
fields: {
favoriteReviews(reviews, { readField }) {
return reviews.filter(review => readField('id', review) !== id)
},
},
})
// Keep Query.currentUser unchanged.
return currentUserRef
},
},
})
},
})
You can use |
🤯😄 Thanks @benjamn! It works but results in this console warning: Does not produce warning: const [removeReview] = useMutation(REMOVE_REVIEW_MUTATION, {
update: (cache) => {
cache.modify({
fields: {
reviews: (reviewRefs, { readField }) =>
reviewRefs.filter((reviewRef) => readField('id', reviewRef) !== id),
},
})
},
}) Produces warning: const [removeReview] = useMutation(REMOVE_REVIEW_MUTATION, {
update: (cache) => {
cache.modify({
fields: {
reviews: (reviewRefs, { readField }) =>
reviewRefs.filter((reviewRef) => readField('id', reviewRef) !== id),
currentUser(currentUserRef) {
cache.modify({
id: currentUserRef.__ref,
fields: {
favoriteReviews: (reviews, { readField }) =>
reviews.filter((review) => readField('id', review) !== id),
},
})
return currentUserRef
},
},
})
},
}) Diff: GraphQLGuide/guide@34ae29e The line referenced in the error is: {reviews.map((review) => (
<Review key={review.id} review={review} />
))} (the mutation code is inside a https://github.com/GraphQLGuide/guide/blob/repro-7061/src/components/ReviewList.js#L40 Related but probably broad issue: #6209 |
Thanks for the response guys. So I didn't realize I could just not pass an Id to get the root query. That got me half way there 🎉 , but now I'm running into the problem of identifying my Connection field with it's set of variables. I've setup the @connection directive to ignore my pagination arguments. So are you telling me that with Would something like this make sense?: cache.modify({
fields: {
[cache.identifyFieldConnectionKey('queryName', variables)]: (cachedSearchIssues) => {
// replace specific query cache entry
},
},
}); Where I'm not quite sure what you mean by
For my use case is that there can potentially be many of these paginated lists on a given page. I need to be able to have separate cache entries for both. Are you saying that in this case I need to build a custom caching mechanism in the fields |
@Nickersona If you're using
If you're using field arguments to differentiate field values, the |
Amazing. Thanks @benjamn I wasn't aware of what was available on the details field. Appreciate the help 🙏, and apologies for derailing the original issue. |
Firstly, thanks for the information in here - I've struggled to find the information in #7061 (comment) documented anywhere. Am I missing something or should the documentation be updated with a more complex example to show how to modify nested data, which I thought was quite a common scenario but perhaps not? Secondly, does anyone know if there is any way to get Typescript types for cache.modify? Right now although this method works it feels extremely fragile to me as its not tied to any of my generated TS types for my queries. |
Hi everyone 👋 This issue has changed quite a lot, I'll try to sum it up:
As long-living issues like this tend to get very confusing, I'm going to close this. If there were any additional points in here that you believe still need addressing, please go ahead and open a new issue for each of them so we can track them in isolation. Thank you! |
Do you have any feedback for the maintainers? Please tell us by taking a one-minute survey. Your responses will help us understand Apollo Client usage and allow us to serve you better. |
Edit: see #7061 (comment) for a description of the current issue
https://www.apollographql.com/docs/react/caching/cache-interaction/#cachemodify has examples of modifying a root query field and the field of a normalized object. I'm wondering how to modify a nested field of a root query field,
Query.currentUser.favoriteReviews
:The old way with read/writeQuery:
I'm looking for something like this (which doesn't work because
fields.currentUser
is supposed to be a function):In this case, the
currentUser
object is not normalized. If it were, I could do:Although it feels weird to mix
readQuery
andmodify
.The text was updated successfully, but these errors were encountered: