Skip to content

Instantly share code, notes, and snippets.

@brunos3d
Last active September 15, 2023 14:35
Show Gist options
  • Save brunos3d/c9e352dcf5c539f9fcb3e13885aaf483 to your computer and use it in GitHub Desktop.
Save brunos3d/c9e352dcf5c539f9fcb3e13885aaf483 to your computer and use it in GitHub Desktop.
Create React Global Context to share between packages and apps.

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>;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment