Skip to content

Instantly share code, notes, and snippets.

@JaggerJo
Created April 15, 2021 20:38
Show Gist options
  • Save JaggerJo/ce7ea9a50915941ab154fd1b0b4ac797 to your computer and use it in GitHub Desktop.
Save JaggerJo/ce7ea9a50915941ab154fd1b0b4ac797 to your computer and use it in GitHub Desktop.
React global state hook fable fsharp
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