Created
March 18, 2021 20:17
-
-
Save NitsanBaleli/74f20be2a5960a9fb5c93e29577126a8 to your computer and use it in GitHub Desktop.
Revisions
-
NitsanBaleli revised this gist
Mar 18, 2021 . No changes.There are no files selected for viewing
-
NitsanBaleli created this gist
Mar 18, 2021 .There are no files selected for viewing
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 charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,39 @@ 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]; }