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

Why not create nodes by List.map? #224

Closed
Martin521 opened this issue Jul 11, 2021 · 4 comments
Closed

Why not create nodes by List.map? #224

Martin521 opened this issue Jul 11, 2021 · 4 comments

Comments

@Martin521
Copy link

The documentation warns against using List.map to create a list of Nodes and recommends forEach instead. Why is this? As far as I can see, forEach creates the list in a way that does not differ from how List.map would do it.
(I do understand the need for using cond, inserting an empty node instead of just dropping a node.)

@Tarmil
Copy link
Member

Tarmil commented Jul 11, 2021

It's a bit complicated, but it's due to the way Blazor's rendering algorithm works. In short, each insertion is associated with a sequence number. These numbers must be consistent between two consecutive renders for the algorithm to work. If you insert items using something like List.map, then as soon as the list has changed length between two consecutive renders, the sequence numbers will be inconsistent. forEach fixes the issue by wrapping the content in a RenderFragment with a sequence that resets for each item.

@Martin521
Copy link
Author

Thank you for the fast reply. It seems then that in my case (lists of constant length) I can ignore it.
(Perhaps the documentation should say "... rendering collections of unknown length using a function such as ...".)
BTW Bolero is really great, thanks for creating and sharing it.

@akhansari
Copy link

akhansari commented Jul 22, 2021

Related question:
Does it make sense a helper like this in order to have the index?

let forEachi (items: 'T list) (mkNode: int32 -> 'T -> Node) : Node =
    forEach {0..items.Length-1} (fun i -> mkNode i items.[i])

@Tarmil
Copy link
Member

Tarmil commented Jul 22, 2021

@akhansari It makes sense, although this implementation is not really optimal, because items.[i] on a list needs to go through the list to find the item. I would suggest something like this instead:

let forEachi items mkNode =
    forEach (Seq.mapi mkNode items) id

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

3 participants