From 0f1cde3a207699edb742dfaada817a815488d594 Mon Sep 17 00:00:00 2001 From: Lenz Weber-Tronic Date: Mon, 24 Jul 2023 16:32:52 +0200 Subject: [PATCH] Restore Apollo Client 3.7 `getApolloContext` behaviour (#11082) * Restore Apollo Client 3.7 `getApolloContext` behaviour * update size-limits --------- Co-authored-by: Jerel Miller --- .changeset/tame-owls-lick.md | 5 ++++ .size-limit.cjs | 4 +-- src/react/context/ApolloContext.ts | 48 +++++++++++------------------- 3 files changed, 24 insertions(+), 33 deletions(-) create mode 100644 .changeset/tame-owls-lick.md diff --git a/.changeset/tame-owls-lick.md b/.changeset/tame-owls-lick.md new file mode 100644 index 00000000000..5ee8c661520 --- /dev/null +++ b/.changeset/tame-owls-lick.md @@ -0,0 +1,5 @@ +--- +'@apollo/client': patch +--- + +Restore Apollo Client 3.7 `getApolloContext` behaviour diff --git a/.size-limit.cjs b/.size-limit.cjs index c23c92cdc7c..9de3cde6686 100644 --- a/.size-limit.cjs +++ b/.size-limit.cjs @@ -1,7 +1,7 @@ const checks = [ { path: "dist/apollo-client.min.cjs", - limit: "37990" + limit: "38000" }, { path: "dist/main.cjs", @@ -10,7 +10,7 @@ const checks = [ { path: "dist/index.js", import: "{ ApolloClient, InMemoryCache, HttpLink }", - limit: "31980" + limit: "31971" }, ...[ "ApolloProvider", diff --git a/src/react/context/ApolloContext.ts b/src/react/context/ApolloContext.ts index 0da5e6bc074..d5d63b139a1 100644 --- a/src/react/context/ApolloContext.ts +++ b/src/react/context/ApolloContext.ts @@ -2,33 +2,20 @@ import * as React from 'react'; import type { ApolloClient } from '../../core/index.js'; import { canUseSymbol } from '../../utilities/index.js'; import type { RenderPromises } from '../ssr/index.js'; -import { global, invariant } from '../../utilities/globals/index.js'; +import { invariant } from '../../utilities/globals/index.js'; export interface ApolloContextValue { client?: ApolloClient; renderPromises?: RenderPromises; } -declare global { - interface Window { - [contextKey]: Map< - typeof React.createContext, - React.Context - >; - } -} - -// To make sure that Apollo Client does not create more than one React context -// per React version, we store that Context in a global Map, keyed by the -// React version. This way, if there are multiple versions of React loaded, -// (e.g. in a Microfrontend environment), each React version will get its own -// Apollo context. -// If there are multiple versions of Apollo Client though, which can happen by -// accident, this can avoid bugs where those multiple Apollo Client versions -// would be unable to "see each other", even if an ApolloProvider was present. -const contextKey: unique symbol = canUseSymbol +// To make sure Apollo Client doesn't create more than one React context +// (which can lead to problems like having an Apollo Client instance added +// in one context, then attempting to retrieve it from another different +// context), a single Apollo context is created and tracked in global state. +const contextKey = canUseSymbol ? Symbol.for('__APOLLO_CONTEXT__') - : ('__APOLLO_CONTEXT__' as any); + : '__APOLLO_CONTEXT__'; export function getApolloContext(): React.Context { invariant( @@ -39,19 +26,18 @@ export function getApolloContext(): React.Context { // TODO: change to React documentation once React documentation contains information about Client Components 'For more information, see https://nextjs.org/docs/getting-started/react-essentials#client-components' ); - - let contextStorage = - global[contextKey] || (global[contextKey] = new Map()); - - let value = contextStorage.get(React.createContext); - if (!value) { - value = Object.assign(React.createContext({}), { - displayName: 'ApolloContext', + + let context = (React.createContext as any)[contextKey] as React.Context; + if (!context) { + Object.defineProperty(React.createContext, contextKey, { + value: context = React.createContext({}), + enumerable: false, + writable: false, + configurable: true, }); - contextStorage.set(React.createContext, value); + context.displayName = 'ApolloContext'; } - - return value; + return context; } /**