Skip to content

Instantly share code, notes, and snippets.

@hachibeeDI
Created July 8, 2019 10:17
Show Gist options
  • Save hachibeeDI/e29938685d704f748e56a199def45125 to your computer and use it in GitHub Desktop.
Save hachibeeDI/e29938685d704f748e56a199def45125 to your computer and use it in GitHub Desktop.
import * as React from 'react';
import { useMemo, useContext, createContext, ReactNode } from 'react';
import { createPortal } from 'react-dom';
type Context = { portalID: string };
const PortalContext = createContext<Context>({} as any);
export function createSplitGate<T>(render: (arg: T) => ReactNode) {
return {
Zone: (props: Context & { children: ReactNode }) => {
const { children, ...ctxValues } = props;
return <PortalContext.Provider value={ctxValues}>{children}</PortalContext.Provider>;
},
ExitGate() {
const { portalID } = useContext(PortalContext);
return <div id={portalID} />;
},
EnterGate(props: { arg: T }) {
const { portalID } = useContext(PortalContext);
const mountTarget = document.getElementById(portalID);
return useMemo(() => {
if (!mountTarget) {
return null;
}
return createPortal(render(props.arg), mountTarget);
}, [props.arg, mountTarget]);
}
};
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment