Created
April 15, 2021 20:38
-
-
Save JaggerJo/ce7ea9a50915941ab154fd1b0b4ac797 to your computer and use it in GitHub Desktop.
React global state hook fable fsharp
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
open Fable.React | |
type private GlobalState = | |
{| current: Map<string, obj> | |
update: Map<string, obj> -> unit |} | |
[<RequireQualifiedAccess>] | |
module GlobalState = | |
let private defaultValue = | |
{| current = Map.empty | |
update = ignore >> failwithf "global state placeholder update function" |} | |
let private globalContext: IContext<GlobalState> = | |
ReactBindings.React.createContext defaultValue | |
let useGlobalState<'state>(identifier: string, defaultValue: 'state) = | |
let state = Hooks.useContext globalContext | |
let value = | |
state.current | |
|> Map.tryFind identifier | |
|> Option.map (fun value -> value :?> 'state) | |
|> Option.defaultValue defaultValue | |
let setValue (value: 'state) = | |
state.current | |
|> Map.add identifier (value :> obj) | |
|> state.update | |
{| current = value | |
update = setValue |} | |
let globalProvider = | |
(* whatever happens, don't modify this to take a list, array, .. instead of a single element. | |
It will not be compiled to an array for some reason / probably a compiler edge case / type checking issue *) | |
FunctionComponent.Of (fun (content: ReactElement) -> | |
let backing: IStateHook<Map<string, obj>> = Hooks.useState Map.empty | |
let wrapped: GlobalState = | |
{| current = backing.current | |
update = backing.update |} | |
contextProvider globalContext wrapped (Array.singleton content) | |
, "GlobalContextProvider") |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment