Is there similar pattern in Lit that uses React.useContext (Context propagation)? #43 #44
Replies: 2 comments 9 replies
-
I think we haven't implemented something like this yet in Fable.Lit. Apparently Lit doesn't implement context by itself, a quick Google search only reveals this npm package. As Lit elements are just HTML elements maybe we could just implement something that looks for a context up in the DOM hierarchy, although this may not work for Hook components which are "virtual" (for that, I assume we would have to pass the context implicitly somehow). @AngelMunoz any ideas? |
Beta Was this translation helpful? Give feedback.
-
Does this seem like a reasonable implementation of UsageCreate Shared Contextmodule WebLit.AppContext
open ElmishStore
type Model =
{ Username: string }
let init () =
{ Username = "Anonymous" }, Cmd.none
type Msg =
| SetUsername of string
let update (msg: Msg) (model: Model) =
match msg with
| SetUsername username ->
{ model with Username = username }, Cmd.none
let store, dispatch = UseContextHook.makeElmishContext init update
Component 1[<HookComponent>]
let Page() =
let ctx = Hook.useContext(AppContext.store)
html $"""
<h1>Welcome to Cat Facts!</h1>
<sl-input
style="width: 300px;"
label="Please enter a username:"
value={ctx.Username}
@sl-change={Ev (fun e -> AppContext.dispatch (AppContext.SetUsername e.target.Value))}></sl-input>
""" Component 2[<LitElement("my-app")>]
let MyApp() =
let model, dispatch = Hook.useElmish(init, update)
let ctx = Hook.useContext(AppContext.store)
// ...
html $"""
<nav>
<div style="float: right; padding: 10px">
<bs-icon src="person-fill" color="white" size="18px"></bs-icon>
{ctx.Username}
</div>
</nav>
// ... Implementationmodule UseContextHook
open Lit
open System
type UseContextStore<'Model>(store: Fable.IStore<'Model>, defaultModel: 'Model) =
member val internal Current = defaultModel with get,set
interface Fable.IStore<'Model> with
member this.Dispose() = store.Dispose()
member this.Update(f) = store.Update(f)
member this.Subscribe(observer: IObserver<'Model>) = store.Subscribe(observer)
let makeElmishContext init update =
let dispose = fun _ -> printfn "store.Dispose()"
let store, dispatch = Store.makeElmish init update dispose ()
let defaultModel = init () |> fst
let ucStore = new UseContextStore<'Model>(store, defaultModel)
ucStore, dispatch
type HookContext with
member ctx.useContext<'Model>(store: UseContextStore<'Model>) =
let model, setModel = ctx.useState(store.Current)
ctx.useEffectOnce (fun () ->
store.Subscribe (fun m ->
store.Current <- m
setModel m
)
)
model
type Hook with
static member inline useContext<'Model>(store: UseContextStore<'Model>) =
Hook.getContext().useContext<'Model>(store)
|
Beta Was this translation helpful? Give feedback.
-
Assuming Lit components are written in MVU. Is there an alternative to write code so we don't have to pass t he message between Parent/Child?
https://zaid-ajaj.github.io/Feliz/#/Feliz/React/ContextPropagation
Beta Was this translation helpful? Give feedback.
All reactions