Keyed nodes documentation
It would be nice to have more documentation about keyed nodes, and the cases where they should be used, where should not be used and how to use them. In Miso code itself are just only a couple specific keyed tags like trKeyed and liKeyed, does it mean keyed nodes should be used only with 2 tags, or if I have a dynamic list of div or input tags - they also should be keyed? I'm asking because I think I might have some issues with dynamic lists of input tags in my apps, when adding and removing in runtime input tags in specific order, the content text inside the input field was put into the wrong place at some point - the text was kinda duplicated if nodes were next to each other. I solved it in an ugly way, running small JSM script to sync input views with input models. Not sure the issue was related to keyed nodes, but if feels like it might be.
https://github.com/functora/functora.github.io/blob/8775227a3c8d06635677229a43cc4350e3a04d0b/ghcjs/currency-converter/src/Main.hs#L284-L295
Hey,
So the keys are supposed to turn the quadratic behavior of modifying large child lists into a linear time operation, and in some happy-path cases even better. If a key attribute is present on a node then miso will attempt to "sync children" according to some heuristics.
The process is documented here in syncChildren.
https://github.com/dmjio/miso/blob/master/jsbits/diff.js#L187
Now I will say if you don't have a key node on all the children in the lists it could cause odd behavior. That might be what you're seeing (duplication etc.), since that's not currently statically enforced, so be sure to check a key is present on all nodes in a child list, and that the keys are unique. Otherwise, if you're using the isomorphic functionality there could be a case where text nodes get combined into a single text node. (edit: this no longer occurs, we handle this case)
If the above cases don't describe what you're seeing I'd recommend attempting to reproduce the duplication behavior as minimally as possible and we can follow up on it with a bug report.
Also, if you're attempting to manipulate the DOM outside of miso, then this can cause undefined behavior. In specific cases where you're operating on a single DOM element it can work fine with the lifecycle hooks. In general I'd say when dealing with child lists you shouldn't need to manipulate things by hand.
Secondly, you can always remove the key attribute and stuff should work just fine. key is purely an optimization when operating on large lists that have a lot of mutations that occur to them
We also use the keyed stuff for benchmarks, and have them tested here:
https://github.com/dmjio/miso/blob/master/tests/diff.test.js
Thanks for reply, @dmjio ! So the keyed is basically an optimization, but there is no reason to not have it in any kind of repeating tags, not only tr and li? The issue with dynamic repeating input and textarea tags mixing the text values of neighbour nodes after node removal is old one, and exists for sure. I was encountering it before with more "pure" examples, unlike example I provided where material design components javascripts theoretically could mess it up. Another issue I "solved" with this syncInputs script was input and textarea cursor being slow, unresponsive and/or jumping around if I set the value attribute in Miso view. It is especially noticeable if user types text into input or textara "too fast". So I didn't set value attribute from Miso view, and syncing value with this script after every update. It's a separate issue, but I still would like to ask - should I use "controlled input" with Miso or not? Could slow update or view function break the controlled inputs in a way I described?
If you can make two issues, one for the keyed node issues, and a separate one for the duplicate text input you’re seeing we can handle each.
Not sure what controlled input means in this context but using miso with input elements should be fine
By "controlled input" I mean code similar to
input_ [value_ (getValue model), onInput setValue]
If user is typing "too fast", some input events might be ignored. However, input events are not ignored in case where
input_ [onInput setValue]
I can not reproduce it with the small trivial Miso application, but for something bigger and not trivial, with longer update and/or view functions, it happens. I did find some very similar old issue in Elm repo, and maybe it might be related, because Miso and Elm are a bit similar:
https://github.com/elm/virtual-dom/issues/107