This example shows abstracts the way Apollo Client creates its Context components to avoid context duplication, you can see the Apollo original code here
The main idea is to give you the ability to share a React Context between packages and applications, like Microfrontends with Module Federation.
// global-context.ts
import * as React from "react";
export function getGlobalContext<P = {}>(
contextKey: string,
defaultValue?: P
): React.Context<P> {
let context = (React.createContext as any)[contextKey];
if (!context) {
Object.defineProperty(React.createContext, contextKey, {
value: (context = React.createContext<P>(defaultValue as P)),
enumerable: false,
writable: false,
configurable: true
});
context.displayName = contextKey;
}
return context;
}
Example of how to use it and create/consume a Global Context
import React from "react";
import { getGlobalContext } from "./global-context";
export type SomeGlobalContextType = {
footerFields: any[];
headerFields: any[];
user: {
name: string;
status: {
isAuthUser: boolean;
};
};
};
export const DefaultSomeGlobalContext: SomeGlobalContextType = {
footerFields: [],
headerFields: [],
user: {
name: "",
status: {
isAuthUser: false
}
}
};
const SomeGlobalContext = getGlobalContext<SomeGlobalContextType>(
"SomeGlobalContext",
DefaultSomeGlobalContext
);
function CustomApp() {
return (
<SomeGlobalContext.Provider
value={{
footerFields: [],
headerFields: [],
user: {
name: "John Doe",
status: {
isAuthUser: true
}
}
}}
>
<Page />
</SomeGlobalContext.Provider>
);
}
function Page() {
const context = React.useContext(SomeGlobalContext);
// intellisense works here
return <div>{context.user.status.isAuthUser}</div>;
}