Skip to content

Commit f2bb0b9

Browse files
authored
useReadQuery/useQueryRefHandlers: Fix a "hook order" warning that might be emitted in React 19 dev mode. (#12341)
* `useReadQuery`/`useQueryRefHandlers`: Fix a "hook order" warning that might be emitted in React 19 dev mode. * change import to type * add two eslint-disables * Clean up Prettier, Size-limit, and Api-Extractor --------- Co-authored-by: phryneas <4282439+phryneas@users.noreply.github.com>
1 parent 219b26b commit f2bb0b9

File tree

4 files changed

+31
-24
lines changed

4 files changed

+31
-24
lines changed

.changeset/large-timers-lay.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@apollo/client": patch
3+
---
4+
5+
`useReadQuery`/`useQueryRefHandlers`: Fix a "hook order" warning that might be emitted in React 19 dev mode.

.size-limits.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
{
2-
"dist/apollo-client.min.cjs": 41643,
2+
"dist/apollo-client.min.cjs": 41642,
33
"import { ApolloClient, InMemoryCache, HttpLink } from \"dist/index.js\" (production)": 34384
44
}

src/react/hooks/useQueryRefHandlers.ts

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ import type {
1616
import type { FetchMoreQueryOptions } from "../../core/watchQueryOptions.js";
1717
import { useApolloClient } from "./useApolloClient.js";
1818
import { wrapHook } from "./internal/index.js";
19+
import type { ApolloClient } from "../../core/ApolloClient.js";
20+
import type { ObservableQuery } from "../../core/ObservableQuery.js";
1921

2022
export interface UseQueryRefHandlersResult<
2123
TData = unknown,
@@ -55,21 +57,19 @@ export function useQueryRefHandlers<
5557
queryRef: QueryRef<TData, TVariables>
5658
): UseQueryRefHandlersResult<TData, TVariables> {
5759
const unwrapped = unwrapQueryRef(queryRef);
60+
const clientOrObsQuery = useApolloClient(
61+
unwrapped ?
62+
// passing an `ObservableQuery` is not supported by the types, but it will
63+
// return any truthy value that is passed in as an override so we cast the result
64+
(unwrapped["observable"] as any)
65+
: undefined
66+
) as ApolloClient<any> | ObservableQuery<TData>;
5867

5968
return wrapHook(
6069
"useQueryRefHandlers",
70+
// eslint-disable-next-line react-compiler/react-compiler
6171
useQueryRefHandlers_,
62-
unwrapped ?
63-
unwrapped["observable"]
64-
// in the case of a "transported" queryRef object, we need to use the
65-
// client that's available to us at the current position in the React tree
66-
// that ApolloClient will then have the job to recreate a real queryRef from
67-
// the transported object
68-
// This is just a context read - it's fine to do this conditionally.
69-
// This hook wrapper also shouldn't be optimized by React Compiler.
70-
// eslint-disable-next-line react-compiler/react-compiler
71-
// eslint-disable-next-line react-hooks/rules-of-hooks
72-
: useApolloClient()
72+
clientOrObsQuery
7373
)(queryRef);
7474
}
7575

src/react/hooks/useReadQuery.ts

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,11 @@ import { __use, wrapHook } from "./internal/index.js";
1010
import { toApolloError } from "./useSuspenseQuery.js";
1111
import { useSyncExternalStore } from "./useSyncExternalStore.js";
1212
import type { ApolloError } from "../../errors/index.js";
13-
import type { NetworkStatus } from "../../core/index.js";
13+
import type {
14+
ApolloClient,
15+
NetworkStatus,
16+
ObservableQuery,
17+
} from "../../core/index.js";
1418
import { useApolloClient } from "./useApolloClient.js";
1519
import type { MaybeMasked } from "../../masking/index.js";
1620

@@ -43,21 +47,19 @@ export function useReadQuery<TData>(
4347
queryRef: QueryRef<TData>
4448
): UseReadQueryResult<TData> {
4549
const unwrapped = unwrapQueryRef(queryRef);
50+
const clientOrObsQuery = useApolloClient(
51+
unwrapped ?
52+
// passing an `ObservableQuery` is not supported by the types, but it will
53+
// return any truthy value that is passed in as an override so we cast the result
54+
(unwrapped["observable"] as any)
55+
: undefined
56+
) as ApolloClient<any> | ObservableQuery<TData>;
4657

4758
return wrapHook(
4859
"useReadQuery",
60+
// eslint-disable-next-line react-compiler/react-compiler
4961
useReadQuery_,
50-
unwrapped ?
51-
unwrapped["observable"]
52-
// in the case of a "transported" queryRef object, we need to use the
53-
// client that's available to us at the current position in the React tree
54-
// that ApolloClient will then have the job to recreate a real queryRef from
55-
// the transported object
56-
// This is just a context read - it's fine to do this conditionally.
57-
// This hook wrapper also shouldn't be optimized by React Compiler.
58-
// eslint-disable-next-line react-compiler/react-compiler
59-
// eslint-disable-next-line react-hooks/rules-of-hooks
60-
: useApolloClient()
62+
clientOrObsQuery
6163
)(queryRef);
6264
}
6365

0 commit comments

Comments
 (0)