Skip to content

Commit

Permalink
useReadQuery/useQueryRefHandlers: Fix a "hook order" warning that…
Browse files Browse the repository at this point in the history
… might be emitted in React 19 dev mode.
  • Loading branch information
phryneas committed Feb 5, 2025
1 parent e63a326 commit bda2682
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 27 deletions.
5 changes: 5 additions & 0 deletions .changeset/large-timers-lay.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@apollo/client": patch
---

`useReadQuery`/`useQueryRefHandlers`: Fix a "hook order" warning that might be emitted in React 19 dev mode.
21 changes: 10 additions & 11 deletions src/react/hooks/useQueryRefHandlers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ import type {
import type { FetchMoreQueryOptions } from "../../core/watchQueryOptions.js";
import { useApolloClient } from "./useApolloClient.js";
import { wrapHook } from "./internal/index.js";
import { ApolloClient } from "../../core/ApolloClient.js";
import type { ObservableQuery } from "../../core/ObservableQuery.js";

export interface UseQueryRefHandlersResult<
TData = unknown,
Expand Down Expand Up @@ -55,21 +57,18 @@ export function useQueryRefHandlers<
queryRef: QueryRef<TData, TVariables>
): UseQueryRefHandlersResult<TData, TVariables> {
const unwrapped = unwrapQueryRef(queryRef);
const clientOrObsQuery = useApolloClient(
unwrapped ?
// passing an `ObservableQuery` is not supported by the types, but it will
// return any truthy value that is passed in as an override so we cast the result
(unwrapped["observable"] as any)
: undefined
) as ApolloClient<any> | ObservableQuery<TData>;

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

Expand Down
29 changes: 13 additions & 16 deletions src/react/hooks/useReadQuery.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,11 @@ import { __use, wrapHook } from "./internal/index.js";
import { toApolloError } from "./useSuspenseQuery.js";
import { useSyncExternalStore } from "./useSyncExternalStore.js";
import type { ApolloError } from "../../errors/index.js";
import type { NetworkStatus } from "../../core/index.js";
import type {
ApolloClient,
NetworkStatus,
ObservableQuery,
} from "../../core/index.js";
import { useApolloClient } from "./useApolloClient.js";
import type { MaybeMasked } from "../../masking/index.js";

Expand Down Expand Up @@ -43,22 +47,15 @@ export function useReadQuery<TData>(
queryRef: QueryRef<TData>
): UseReadQueryResult<TData> {
const unwrapped = unwrapQueryRef(queryRef);

return wrapHook(
"useReadQuery",
useReadQuery_,
const clientOrObsQuery = useApolloClient(
unwrapped ?
unwrapped["observable"]
// in the case of a "transported" queryRef object, we need to use the
// client that's available to us at the current position in the React tree
// that ApolloClient will then have the job to recreate a real queryRef from
// the transported object
// This is just a context read - it's fine to do this conditionally.
// This hook wrapper also shouldn't be optimized by React Compiler.
// eslint-disable-next-line react-compiler/react-compiler
// eslint-disable-next-line react-hooks/rules-of-hooks
: useApolloClient()
)(queryRef);
// passing an `ObservableQuery` is not supported by the types, but it will
// return any truthy value that is passed in as an override so we cast the result
(unwrapped["observable"] as any)
: undefined
) as ApolloClient<any> | ObservableQuery<TData>;

return wrapHook("useReadQuery", useReadQuery_, clientOrObsQuery)(queryRef);
}

function useReadQuery_<TData>(
Expand Down

0 comments on commit bda2682

Please sign in to comment.