ml-in-barcelona / jsoo-react

js_of_ocaml bindings for ReactJS. Based on ReasonReact.
https://ml-in-barcelona.github.io/jsoo-react
MIT License
138 stars 19 forks source link

Lazy components #46

Open Voronar opened 3 years ago

Voronar commented 3 years ago

Any workarounds for this feature? I tried this approach (https://github.com/Voronar/jsoo-webpack/blob/master/main.ml#L5), but it is awful.

jchavarri commented 3 years ago

There are currently a couple of things missing to support this at least at least minimally:

a) bindings to Suspense and lazy b) a proper way to define "external" components that are used from JS (as I see in the example link there's an import of a JS library)

However, there might be a workaround for the time being:

  1. Move all the lazy loading logic to a .js file:
// in antdTable.js file
joo_global_object.antdTable = require("react").lazy(function () { return import('antd/lib/table/Table')});
  1. Add the js file above to dune so the global gets include in final bundle, like this:

https://github.com/jchavarri/jsoo-react/blob/3d805465c49a0a334c2c832145e327987eccbbc9/lib/dune#L7

it'd be (javascript_files antdTable.js) in this case.

  1. Create "manual" bindings to the component in OCaml code:
module AntdTable = struct
  let makeProps : foo:string -> unit -> < foo: string Js.readonly_prop > Js.t =
   fun ~foo () ->
    let open Js.Unsafe in
    obj [|("foo", inject (Js.string foo))|]

  let make :
      ( < foo: Js.js_string Js.t Js.readonly_prop > Js.t
      , React.element )
      React.componentLike =
    Js.Unsafe.global##.antdTable
end

The step 3 is what would be automated with the section b) mentioned above.

Note I haven't tried any of this 😁 so there might be things that I'm missing.