diff --git a/.changeset/large-beers-rhyme.md b/.changeset/large-beers-rhyme.md new file mode 100644 index 00000000000..392e4d1a199 --- /dev/null +++ b/.changeset/large-beers-rhyme.md @@ -0,0 +1,5 @@ +--- +'@apollo/client': patch +--- + +Use `import * as React` everywhere. This prevents an error when importing `@apollo/client` in a React Server component. (see [#10974](https://github.com/apollographql/apollo-client/issues/10974)) diff --git a/src/react/hooks/internal/__use.ts b/src/react/hooks/internal/__use.ts index 936f8a382b2..b9d32d180b8 100644 --- a/src/react/hooks/internal/__use.ts +++ b/src/react/hooks/internal/__use.ts @@ -1,5 +1,5 @@ import { wrapPromiseWithState } from '../../../utilities'; -import React from 'react'; +import * as React from 'react'; type Use = (promise: Promise) => T; // Prevent webpack from complaining about our feature detection of the diff --git a/src/react/hooks/internal/useDeepMemo.ts b/src/react/hooks/internal/useDeepMemo.ts index 5f9c3cb2351..ac96206ce9b 100644 --- a/src/react/hooks/internal/useDeepMemo.ts +++ b/src/react/hooks/internal/useDeepMemo.ts @@ -1,12 +1,12 @@ import type { DependencyList } from 'react'; -import { useRef } from 'react'; +import * as React from 'react'; import { equal } from '@wry/equality'; export function useDeepMemo( memoFn: () => TValue, deps: DependencyList ) { - const ref = useRef<{ deps: DependencyList; value: TValue }>(); + const ref = React.useRef<{ deps: DependencyList; value: TValue }>(); if (!ref.current || !equal(ref.current.deps, deps)) { ref.current = { value: memoFn(), deps }; diff --git a/src/react/hooks/internal/useIsomorphicLayoutEffect.ts b/src/react/hooks/internal/useIsomorphicLayoutEffect.ts index b8bd88b645d..b14e3dacdf2 100644 --- a/src/react/hooks/internal/useIsomorphicLayoutEffect.ts +++ b/src/react/hooks/internal/useIsomorphicLayoutEffect.ts @@ -1,6 +1,8 @@ -import { useLayoutEffect, useEffect } from 'react'; +import * as React from 'react'; import { canUseDOM } from '../../../utilities'; +const { useLayoutEffect, useEffect } = React; + // use canUseDOM here instead of canUseLayoutEffect because we want to be able // to use useLayoutEffect in our jest tests. useLayoutEffect seems to work fine // in useSuspenseQuery tests, but to honor the original comment about the diff --git a/src/react/hooks/internal/useStrictModeSafeCleanupEffect.ts b/src/react/hooks/internal/useStrictModeSafeCleanupEffect.ts index 6c4528fd20b..dc4577a7247 100644 --- a/src/react/hooks/internal/useStrictModeSafeCleanupEffect.ts +++ b/src/react/hooks/internal/useStrictModeSafeCleanupEffect.ts @@ -1,9 +1,9 @@ -import { useEffect } from 'react'; +import * as React from 'react'; export function useStrictModeSafeCleanupEffect(cleanup: () => void) { let timeout: NodeJS.Timeout; - useEffect(() => { + React.useEffect(() => { clearTimeout(timeout); return () => { diff --git a/src/react/hooks/useApolloClient.ts b/src/react/hooks/useApolloClient.ts index 61a7adf8d16..e28065534ab 100644 --- a/src/react/hooks/useApolloClient.ts +++ b/src/react/hooks/useApolloClient.ts @@ -1,12 +1,12 @@ import { invariant } from '../../utilities/globals'; -import { useContext } from 'react'; +import * as React from 'react'; import type { ApolloClient } from '../../core'; import { getApolloContext } from '../context'; export function useApolloClient( override?: ApolloClient, ): ApolloClient { - const context = useContext(getApolloContext()); + const context = React.useContext(getApolloContext()); const client = override || context.client; invariant( !!client, diff --git a/src/react/hooks/useBackgroundQuery.ts b/src/react/hooks/useBackgroundQuery.ts index ebd3dfcc19e..0daad4ebb8a 100644 --- a/src/react/hooks/useBackgroundQuery.ts +++ b/src/react/hooks/useBackgroundQuery.ts @@ -1,4 +1,4 @@ -import { useEffect, useState, useMemo, useCallback } from 'react'; +import * as React from 'react'; import type { DocumentNode, OperationVariables, @@ -20,6 +20,8 @@ import { canonicalStringify } from '../../cache'; import type { DeepPartial } from '../../utilities'; import { invariant } from '../../utilities/globals'; +const { useEffect, useState, useMemo, useCallback } = React; + export type UseBackgroundQueryResult< TData = unknown, TVariables extends OperationVariables = OperationVariables diff --git a/src/react/hooks/useLazyQuery.ts b/src/react/hooks/useLazyQuery.ts index 20b82558702..901b493715e 100644 --- a/src/react/hooks/useLazyQuery.ts +++ b/src/react/hooks/useLazyQuery.ts @@ -1,6 +1,6 @@ import type { DocumentNode } from 'graphql'; import type { TypedDocumentNode } from '@graphql-typed-document-node/core'; -import { useCallback, useMemo, useRef } from 'react'; +import * as React from 'react'; import type { OperationVariables } from '../../core'; import { mergeOptions } from '../../utilities'; @@ -14,6 +14,8 @@ import type { import { useInternalState } from './useQuery'; import { useApolloClient } from './useApolloClient'; +const { useCallback, useMemo, useRef } = React; + // The following methods, when called will execute the query, regardless of // whether the useLazyQuery execute function was called before. const EAGER_METHODS = [ diff --git a/src/react/hooks/useMutation.ts b/src/react/hooks/useMutation.ts index 7f4416c63b3..12d624a49b2 100644 --- a/src/react/hooks/useMutation.ts +++ b/src/react/hooks/useMutation.ts @@ -1,4 +1,4 @@ -import { useCallback, useEffect, useRef, useState } from 'react'; +import * as React from 'react'; import type { DocumentNode } from 'graphql'; import type { TypedDocumentNode } from '@graphql-typed-document-node/core'; import type { @@ -21,6 +21,8 @@ import { DocumentType, verifyDocumentType } from '../parser'; import { ApolloError } from '../../errors'; import { useApolloClient } from './useApolloClient'; +const { useCallback, useEffect, useRef, useState } = React; + export function useMutation< TData = any, TVariables = OperationVariables, diff --git a/src/react/hooks/useQuery.ts b/src/react/hooks/useQuery.ts index 34841feaefa..d417e77acbf 100644 --- a/src/react/hooks/useQuery.ts +++ b/src/react/hooks/useQuery.ts @@ -1,12 +1,6 @@ import { invariant } from '../../utilities/globals'; -import { - useCallback, - useContext, - useMemo, - useRef, - useState, -} from 'react'; +import * as React from 'react'; import { useSyncExternalStore } from './useSyncExternalStore'; import { equal } from '@wry/equality'; @@ -36,6 +30,14 @@ import { DocumentType, verifyDocumentType } from '../parser'; import { useApolloClient } from './useApolloClient'; import { canUseWeakMap, compact, isNonEmptyArray, maybeDeepFreeze } from '../../utilities'; +const { + useCallback, + useContext, + useMemo, + useRef, + useState, +} = React; + const { prototype: { hasOwnProperty, diff --git a/src/react/hooks/useReactiveVar.ts b/src/react/hooks/useReactiveVar.ts index b9b96090ab5..ac9b2993ca7 100644 --- a/src/react/hooks/useReactiveVar.ts +++ b/src/react/hooks/useReactiveVar.ts @@ -1,6 +1,8 @@ -import { useEffect, useState } from 'react'; +import * as React from 'react'; import type { ReactiveVar } from '../../core'; +const { useEffect, useState } = React; + export function useReactiveVar(rv: ReactiveVar): T { const value = rv(); diff --git a/src/react/hooks/useSubscription.ts b/src/react/hooks/useSubscription.ts index 5da11a014ae..201792481d6 100644 --- a/src/react/hooks/useSubscription.ts +++ b/src/react/hooks/useSubscription.ts @@ -1,5 +1,5 @@ import { invariant } from '../../utilities/globals'; -import { useState, useRef, useEffect } from 'react'; +import * as React from 'react'; import type { DocumentNode } from 'graphql'; import type { TypedDocumentNode } from '@graphql-typed-document-node/core'; import { equal } from '@wry/equality'; @@ -13,6 +13,8 @@ import type { import type { OperationVariables } from '../../core'; import { useApolloClient } from './useApolloClient'; +const { useState, useRef, useEffect } = React; + export function useSubscription( subscription: DocumentNode | TypedDocumentNode, options?: SubscriptionHookOptions, NoInfer>, diff --git a/src/react/hooks/useSuspenseCache.ts b/src/react/hooks/useSuspenseCache.ts index 5dd01c18df3..8492b618021 100644 --- a/src/react/hooks/useSuspenseCache.ts +++ b/src/react/hooks/useSuspenseCache.ts @@ -1,10 +1,10 @@ -import { useContext } from 'react'; +import * as React from 'react'; import { getApolloContext } from '../context'; import { invariant } from '../../utilities/globals'; import type { SuspenseCache } from '../cache'; export function useSuspenseCache(override?: SuspenseCache) { - const context = useContext(getApolloContext()); + const context = React.useContext(getApolloContext()); const suspenseCache = override || context.suspenseCache; invariant( diff --git a/src/react/hooks/useSuspenseQuery.ts b/src/react/hooks/useSuspenseQuery.ts index 2d8d4d7659d..5270d15f22f 100644 --- a/src/react/hooks/useSuspenseQuery.ts +++ b/src/react/hooks/useSuspenseQuery.ts @@ -1,5 +1,5 @@ import { invariant, __DEV__ } from '../../utilities/globals'; -import { useRef, useCallback, useMemo, useEffect, useState } from 'react'; +import * as React from 'react'; import type { ApolloClient, ApolloQueryResult, @@ -25,6 +25,7 @@ import { useSuspenseCache } from './useSuspenseCache'; import type { QueryReference } from '../cache/QueryReference'; import { canonicalStringify } from '../../cache'; +const { useRef, useCallback, useMemo, useEffect, useState } = React; export interface UseSuspenseQueryResult< TData = unknown, TVariables extends OperationVariables = OperationVariables