Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Keyed nodes documentation #745

Open
functora opened this issue Sep 19, 2024 · 6 comments
Open

Keyed nodes documentation #745

functora opened this issue Sep 19, 2024 · 6 comments

Comments

@functora
Copy link

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

@dmjio
Copy link
Owner

dmjio commented Sep 19, 2024

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.

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.

@dmjio
Copy link
Owner

dmjio commented Sep 19, 2024

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

@dmjio
Copy link
Owner

dmjio commented Sep 19, 2024

We also use the keyed stuff for benchmarks, and have them tested here:

https://github.com/dmjio/miso/blob/master/tests/diff.test.js

@functora
Copy link
Author

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?

@dmjio
Copy link
Owner

dmjio commented Sep 21, 2024

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

@functora
Copy link
Author

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:
elm/virtual-dom#107

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants