Module type App_intf.S
val on_startup : schedule_action:(Action.t -> unit) -> Model.t -> State.t Async_kernel.Deferred.t
on_startup
is called once, right after the initial DOM is set to the view that corresponds to the initial state. This is useful for doing things like starting up async processes. Note that this part of the computation does not support any incrementality, since it's only run once.
val create : Model.t Incr.t -> old_model:Model.t Incr.t -> inject:(Action.t -> Virtual_dom.Vdom.Event.t) -> (Action.t, Model.t, State.t) Component.t Incr.t
create
is a function that incrementally constructs aComponent
. Note that aComponent
supports functions likeapply_action
, which return a newModel.t
, without taking a model as an explicit input. The intent is forapply_action
to have access to the current model via its constructionHere's an example of how this might look in practice.
module Model = struct type t = { counter : int } [@@deriving fields, compare] let cutoff t1 t2 = compare t1 t2 = 0 end module State = struct type t = unit end module Action = struct type t = Increment [@@deriving sexp_of] let should_log _ = false end let initial_model = { Model.counter = 0 } let on_startup ~schedule_actions _model = every (Time_ns.Span.of_sec 1.) (fun () -> schedule_actions [ Action.Increment ]); Deferred.unit ;; let create model ~old_model:_ ~inject:_ = let open Incr.Let_syntax in let%map apply_action = let%map counter = model >>| Model.counter in fun (Increment : Action.t) _ ~schedule_actions:_ -> { Model.counter = counter + 1 } and view = let%map counter = let%map counter = model >>| Model.counter in Vdom.Node.div [] [ Vdom.Node.text (Int.to_string counter) ] in Vdom.Node.body [] [ counter ] and model = model in (* Note that we don't include [on_display] or [update_visibility], since these are optional arguments *) Component.create ~apply_action model view ;;
The full code for this example can be found in examples/counter.