diff options
Diffstat (limited to 'src/unstated-next.tsx')
-rw-r--r-- | src/unstated-next.tsx | 33 |
1 files changed, 33 insertions, 0 deletions
diff --git a/src/unstated-next.tsx b/src/unstated-next.tsx new file mode 100644 index 0000000..b19f8ba --- /dev/null +++ b/src/unstated-next.tsx @@ -0,0 +1,33 @@ +import React from "react" + +interface ContainerProviderProps { + children: React.ReactNode +} + +interface Container<Value> { + Provider: React.ComponentType<ContainerProviderProps> + useContainer: () => Value +} + +export function createContainer<Value>(useHook: () => Value): Container<Value> { + let Context = React.createContext<Value | null>(null) + + function Provider(props: ContainerProviderProps) { + let value = useHook() + return <Context.Provider value={value}>{props.children}</Context.Provider> + } + + function useContainer(): Value { + let value = React.useContext(Context) + if (value === null) { + throw new Error("Component must be wrapped with <Container.Provider>") + } + return value + } + + return { Provider, useContainer } +} + +export function useContainer<Value>(container: Container<Value>): Value { + return container.useContainer() +} |