-
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
Component not re-render in apollo-link-state after upgrading apollo-cache-inmemory to 1.3.* #3992
Comments
Your first and second link have the same behavior for me. I'm using the latest chrome version, i don't know if this is relevant but just throwing it out there. |
@JoviDeCroock |
Yes, maybe i should mention this the same behavior is that they both are working. |
@JoviDeCroock However, |
That's a pretty odd issue, is there some way to reproduce it consistently for others aswell? |
One more update: |
There is some info about this and how state changes are broadcasted in the local-state slack channel provided by @benjamn |
Like to slack comment about a possible work around. https://apollographql.slack.com/archives/C87A16E8Y/p1539111592000100 |
@carllippert |
As a general note, you shouldn't be mutating the results returned from the cache, unless you are careful to re-write them immediately, since those objects may be returned for future reads. Make copies of the data you read from the cache, if you plan on changing the contents of the objects. If I'm diagnosing this problem correctly, perhaps we should be |
Having the same issue. |
|
@OurMajesty Can you put together a small reproduction? |
Thank you for response, I'll try.
Tried to change push to concat and assignment to object spread, but no luck. |
https://codesandbox.io/s/q7rkm6y1ow |
@benjamn @OurMajesty The only way it can be worked, is to clear the cached data, then save the new data in React Native and Chromium. Like this (Example: https://codesandbox.io/s/wnxmzmm7o7):
|
@benjamn If that's the case (we shouldn't be mutating the cache results) then we need to update the docs, which are mutating the cache results. So if this is expected behavior, then it is surely a breaking change, right? |
Similar issue here going from 1.2.10 to 1.3.5, though I'm using I also did this based on the documentation examples mutating the cache results: update: (proxy, { data: { createTodo } }) => {
const data = proxy.readQuery({ query });
data.todos.push(createTodo);
proxy.writeQuery({ query, data });
} |
If I do writeQuery in update method of mutation It doesn't call rerender of my component with query like in writeQuery |
Should help fix #3992. As #3992 (and specifically the reproduction that @OurMajesty provided at https://codesandbox.io/s/q7rkm6y1ow) demonstrates, since the InMemoryCache may return the same object for multiple reads (when the data have not changed), the previousResult is often exactly (===) the same object as newData.result, which was causing the code removed by this commit to return early instead of broadcasting the watch. This early return was unsafe, because the contents of the object may have changed since they were previously broadcast, so we actually do need to report those modifications, even though the object reference is the same. In other words, `previousResult === newData.result` does not imply "nothing has changed," as I mistakenly assumed in this discussion: #3394 (comment) In the longer term, I would like to eliminate the previousResult logic entirely, since it seems redundant now that we can precisely track changes to the store, but for now it's important for backwards compatibility. Specifically, previousResult still provides a way to prefer the previous object if it is structurally identical to the new object, though that preference is moot when `previousResult === newData.result`. The previousResult object should never be used as a basis for skipping broadcasts. Only the application developer can decide whether === object identity means it's safe to skip rendering, likely in the context of a larger design which treats cache results as immutable data. The job of the InMemoryCache is to make no unsound assumptions, and broadcast results whenever they may have changed.
Should help with #3992. Though deep cloning and isEqual testing are obviously more expensive than relying on === equality, the reality is that lastResult may have been modified since it was previously recorded, so === equality is useless for determining isDifferentResult. A defensive copy is the only way to make sure we get this right.
Fix incoming with #4032. |
I believe this has been fixed with Please try updating those packages, and comment here with your findings (good or bad)! |
UPD: That was my problem, ensure you update both
|
nevermind, the problem was because I didn't update |
I have an issue with updating an array of object in cache in Working example:
The component will not re-render when the
|
@stonecold123 Can you update your CodeSandbox reproduction above to demonstrate the issue? |
@benjamn 1.3.6 did not fix a similar issue we had after upgrading to 1.3.5. We don't have the issue with 1.2.10. We observed that changing direct fields of an object works just fine but any field with nested fields (in our case with two level nesting) causes issues. The data we get from query was not changed.
Changes to x, y are gine, but changes to z.b.field1 are not reflected back. I can provide a test case if you like. |
@cagdastulek Please do throw together a CodeSandbox reproduction. |
having the same issue |
https://codesandbox.io/s/k027kz5243 I'm doing something very similar to the The sandbox example is using apollo-link-state instead of an actual API endpoint. If I update the data in the link state's resolver for the mutation using However, if I comment that code out and just return the newly added item (similar to what the frontend would see as a response from our API) and instead use I also threw a logging line in the |
This commit is a more conservative version of e66027c We still need to make a deep clone of observableQuery.lastResult in order to determine if future results are different (see #3992), but we can restrict the use of that snapshot to a single method, rather than replacing observableQuery.lastResult with the snapshot. Should help with #4054.
This commit is a more conservative version of e66027c We still need to make a deep clone of observableQuery.lastResult in order to determine if future results are different (see #3992), but we can restrict the use of that snapshot to a single method, rather than replacing observableQuery.lastResult with the snapshot. Should help with #4054.
This commit is a more conservative version of e66027c We still need to make a deep clone of observableQuery.lastResult in order to determine if future results are different (see #3992), but we can restrict the use of that snapshot to a single method, rather than replacing observableQuery.lastResult with the snapshot. Should help with #4054 and #4031.
I also ran into the similar issue when reading nested fields from the store. Everything in the store is correct after calling a mutation, but still getting the old data in the After diving into node_modules/apollo-cache-inmemory, I find out that it gets correct new data from the store when I removed the following lines: apollo-client/packages/apollo-cache-inmemory/src/readFromStore.ts Lines 110 to 154 in 31b0ee4
|
@dmarkow I believe your problem is fixed in @chentsulin Not sure I can help you without a reproduction. Please make sure you're using the latest versions of |
@benjamn It sure does. Thank you! |
Intended outcome:
I use apollo link state to save an array of objects to the local client. In apollo-cache-inmemory 1.2.10, the component is able to re-render on pushing new items to the array or deleting one item from the array. After upgrading to 1.3.5, I expected everything would stay the same.
Actual outcome:
However the component fails to re-render at all with 1.3.*.
How to reproduce the issue:
apollo-cache-inmemory 1.2.10:
https://codesandbox.io/s/l99l9r1ml9 (There's an issue with codesandbox. I have to double click the buttons to trigger the re-render, but on my local, there's no such issue.)
apollo-cache-inmemory 1.3.5
https://codesandbox.io/s/8xqn9mz0l (It doesn't work at all, even if I double click either buttons)
Versions
The text was updated successfully, but these errors were encountered: