After some time, RLists don’t update anymore in a browser (tested on Edge and Firefox). There’s no error in the console, so I don’t know what went wrong. Any idea?
Here’s a reproducer:
open Js_of_ocaml
open Js_of_ocaml_tyxml.Tyxml_js
open ReactiveData
open Html
let app () =
let l, h = RList.create [] in
let out = l |> RList.map (fun x -> li [txt x]) |> R.Html.ul in
let counter = ref 0 in
div [
button [txt "append"] ~a:[a_onclick (fun _ ->
RList.cons (string_of_int !counter) h;
incr counter;
false
)];
out;
]
let _ =
let open Dom_html in
Dom_events.listen document Event.domContentLoaded (fun _ _ ->
let add () =
let elt = (To_dom.of_div (app ()) :> Dom.node Js.t) in
ignore @@ document##.body##appendChild elt
in
add ();
add ();
true
)
If so, what should I keep a reference to? It still fails when app, l, and h are global:
let l, h = RList.create []
let app =
let out = l |> RList.map (fun x -> li [txt x]) |> R.Html.ul in
let counter = ref 0 in
div [
button [txt "append"] ~a:[a_onclick (fun _ ->
RList.cons (string_of_int !counter) h;
incr counter;
false
)];
out;
]
I’ve followed its execution using a debugger. The internal list gets updated, but DOM nodes aren’t. I guess this is related to this comment in tyxml_js.ml…
I’ve tried fixing the aforementioned comments in this commit, it still doesn’t work. I don’t know why: the same technique works in this sample CLI program…
It has no effect. When digging up the output JS, it looks the same with and without using Sys.opaque_identity:
function update_children(dom,nodes)
{removeChildren(dom);
var _j_=0;
function _k_(param,msg)
{if(0 === msg[0])
;} //...
caml_call3(ReactiveData[1][11],_k_,nodes,_j_);
function _l_(param){return 0}
var _m_=caml_call1(ReactiveData[1][13],nodes);
caml_call2(React[1][3],_m_,_l_);
return 0}
I compile my sample program in an up-to-date tree of js_of_ocaml. I’m reinstalling the latest version with opam, just in case… Thanks for the heads-up!
Unfortunately, it still doesn’t. I had resorted to the same trick there and using ignore was enough for the thunk to capture the variable: does it indicate that the issue is related to js_of_ocaml optimizations?
I guess I would get an error in the browser’s console (there’s nothing). Besides, RList.create doesn’t use never and returns a Mutable list, so I don’t see any problem there.
I’ve pushed a semi-automated reproducer, so we don’t have to repeatedly press a button anymore. It looks time-dependent; that’s consistent with what I read about WeakRef on MDN.