OvermindDL1 / bucklescript-tea

TEA for Bucklescript
Other
600 stars 46 forks source link

Question: TEA with Reason+React Native #93

Open bstro opened 6 years ago

bstro commented 6 years ago

Is it feasible to use bucklescript-tea for handling logic+side-effects and bs-react-native for the view? Thanks!

OvermindDL1 commented 6 years ago

It kind of is by calling out to the react handler from the view (using stateless react views) and just using an empty element as the return value. Not entirely pretty, though it would be easier if I get around to finishing the Custom Element handling in the vdom (patches welcome, or keep pinging me to get it done!) ^.^

I love your avatar, I thought my notification popup broke somehow (especially since it is not a webview)! Lol!

I'd be curious to hear about your experiments in it as such? It's definitely a bit of a hack, but is doable!

bstro commented 6 years ago

This may be asking too much, but would it be terribly time consuming to throw together a super quick example? I'm quite new to this repo as well as Reason.

OvermindDL1 commented 6 years ago

I don't use react and don't really know it well enough to use it, but as a start if you look at the example project on the main readme you could replace the view function with something like (this is all in OCaml syntax as that is what I know, but should be trivially changeable to reason as they are pretty close):

let view model =
  let _ = my_react_call model in
  span [] []

Where my_react_call just delegates outside of it all passing the model out (or you could pass individual arguments). If you are wanting to essentially 'mount' the react side into the view properly then something more like this perhaps (typed inline here, untested, etc...):

open Tea
open Tea.App
open Tea.Html

type msg =
  | StateUpdate
  | Increment
  | Decrement
  | Reset
  | Set of int

type model = {
  state : int;
  count : int;
}

let init () = {state=0; count=4}, Cmd.none

let update {state; count} = function
  | StateUpdate -> {state=state+1; count}, Cmd.none
  | Increment -> {state; model=model + 1}, Cmd.none
  | Decrement -> {state; model=model - 1}, Cmd.none
  | Reset -> {state; model=0}, Cmd.none
  | Set v -> {state; model=v}, Cmd.none

let subscriptions {state} =
  if state > 2
  then Tea.Sub.none
  else AnimationFrame.times (fun _ -> StateUpdate)

let view {state; count} =
  let _ = if state > 2
    then let _ = my_react_call count in () else () in
  span [] []

let main =
  program {
    init;
    update;
    view;
    subscriptions;
    shutdown = (fun _model -> Cmd.none); (* Can do something to react here on shutdown if needed *)
  }

And the react app would inject messages into this app that is returned from the main call to inject messages. You can 'construct' a message by calling the right exposed function on this module to pass to that message injection. This will all be easier once I get Custom Nodes in though. ^.^;

If you can setup a repo that I can clone of what you have so far then I can try to PR help in to it too to figure out the best way to handle it all. :-)

bstro commented 6 years ago

Thanks a ton! This is super helpful.

alltonp commented 4 years ago

This would be really awesome, did you ever get it going?

OvermindDL1 commented 4 years ago

I don't use React but a PR would be a good place to contribute missing functionality for it. :-)