Created
March 18, 2021 20:17
-
-
Save NitsanBaleli/74f20be2a5960a9fb5c93e29577126a8 to your computer and use it in GitHub Desktop.
based on Tanner Linsley's https://gist.github.com/tannerlinsley/a78598f751ef0d9f9d8d9973e5ec9ff6
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import * as React from "react"; | |
import { useState, useMemo, Dispatch, SetStateAction } from "react"; | |
type IContext<T> = [T, Dispatch<SetStateAction<T>>]; | |
type ProviderProps<T> = { initialValue: T; children: React.ReactNode }; | |
export function makeStore<T>(): [ | |
(props: ProviderProps<T>) => React.ReactElement, | |
() => IContext<T> | |
] { | |
// Make a context for the store | |
const context = React.createContext<IContext<T>>(null); | |
// Make a provider that takes an initialValue | |
const Provider = ({ initialValue, children }: ProviderProps<T>) => { | |
// Make a new state instance (could even use immer here!) | |
const [state, setState] = useState<T>(initialValue); | |
// Memoize the context value to update when the state does | |
const contextValue = useMemo<IContext<T>>(() => [state, setState], [ | |
state, | |
]); | |
// Provide the store to children | |
return ( | |
<context.Provider value={contextValue}>{children}</context.Provider> | |
); | |
}; | |
// A hook to help consume the store | |
const useStore = () => { | |
const _context = React.useContext<IContext<T>>(context); | |
if (_context === undefined) { | |
throw new Error("context must be used inside its Provider"); | |
} | |
return _context; | |
}; | |
return [Provider, useStore]; | |
} |
Author
NitsanBaleli
commented
Mar 18, 2021
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment