Skip to content

Commit

Permalink
Detect if diff changes between useFragment and cache.watch (#10212
Browse files Browse the repository at this point in the history
)
  • Loading branch information
benjamn authored Oct 20, 2022
1 parent b03dff2 commit 81bc6b4
Show file tree
Hide file tree
Showing 3 changed files with 12 additions and 41 deletions.
5 changes: 4 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
## Apollo Client 3.7.1
## Apollo Client 3.7.1 (unreleased)

### Bug fixes

- Fix issue where `loading` remains `true` after `observer.refetch` is called repeatedly with different variables when the same data are returned. <br/>
[@alessbell](https://github.com/alessbell) in [#10143](https://github.com/apollographql/apollo-client/pull/10143)

- Fix race condition where `useFragment_experimental` could receive cache updates before initially calling `cache.watch` in `useEffect`. <br/>
[@benjamn](https://github.com/benjamn) in [#10212](https://github.com/apollographql/apollo-client/pull/10212)

## Apollo Client 3.7.0 (2022-09-30)

### New Features
Expand Down
42 changes: 6 additions & 36 deletions src/react/hooks/__tests__/useFragment.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ import {
ApolloLink,
} from "../../../core";
import { useQuery } from "../useQuery";
import { FragmentSpreadNode, OperationDefinitionNode, Kind } from "graphql";

describe("useFragment", () => {
it("is importable and callable", () => {
Expand Down Expand Up @@ -224,46 +223,17 @@ describe("useFragment", () => {
"item 5",
]);

let resolveAfterItem4Updated: () => void;
const item4UpdatePromise = new Promise<void>((resolve, reject) => {
resolveAfterItem4Updated = resolve;
setTimeout(() => {
reject(new Error("timed out"));
}, 100);
});

act(() => {
cache.batch({
update(cache) {
cache.writeFragment({
fragment: ItemFragment,
data: {
__typename: "Item",
id: 4,
text: "Item #4 updated",
},
});
},

onWatchUpdated(watch, diff) {
const [def] = watch.query.definitions as OperationDefinitionNode[];
const fragmentSpread = def.selectionSet.selections[0] as FragmentSpreadNode;
expect(fragmentSpread.kind).toBe(Kind.FRAGMENT_SPREAD);
expect(fragmentSpread.name.value).toBe("ItemFragment");

expect(diff.complete).toBe(true);
expect(diff.result).toEqual({
__typename: 'Item',
text: 'Item #4 updated',
});

resolveAfterItem4Updated();
cache.writeFragment({
fragment: ItemFragment,
data: {
__typename: "Item",
id: 4,
text: "Item #4 updated",
},
});
});

await item4UpdatePromise;

await waitFor(() => {
expect(getItemTexts()).toEqual([
"Item #1",
Expand Down
6 changes: 2 additions & 4 deletions src/react/hooks/useFragment.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,16 +73,14 @@ export function useFragment_experimental<TData, TVars>(

return useSyncExternalStore(
forceUpdate => {
let immediate = true;
return cache.watch({
...diffOptions,
immediate,
immediate: true,
callback(diff) {
if (!immediate && !equal(diff, latestDiff)) {
if (!equal(diff, latestDiff)) {
resultRef.current = diffToResult(latestDiff = diff);
forceUpdate();
}
immediate = false;
},
});
},
Expand Down

0 comments on commit 81bc6b4

Please sign in to comment.