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

[hdom] - iterators disappear after initial render #42

Closed
den1k opened this issue Sep 10, 2018 · 2 comments
Closed

[hdom] - iterators disappear after initial render #42

den1k opened this issue Sep 10, 2018 · 2 comments

Comments

@den1k
Copy link

den1k commented Sep 10, 2018

I was looking for a shorter way to write components that dynamically create inner child-nodes from a collection.

For example, a basic list component:

[
  "ul",
  tx.transduce(tx.map(i => ["li", i]), tx.push(), tx.range(1, 6))
]

The transduce transduce and the push() seem superfluous to me. I tried:

["ul", tx.map(i => ["li", i], tx.range(1, 6))]

and

["ul", tx.iterator(tx.map(i => ["li", i]), [...tx.range(1, 6)])],

to compose transducers.

Both approaches work fine on first render and then never again. I assume that's because the overloaded map and iterator turn into generator functions? Generator functions are probably not very useful for hdom if they can only run once. However, it looks like iterators can also be computed several times though I'm not sure that's desirable.

Getting back to the issue, is there a shorter way to express the list component above?

@den1k den1k changed the title [hdom] - only once iterators disappear after initial render [hdom] - iterators disappear after initial render Sep 10, 2018
@postspectacular
Copy link
Member

Iterators can of course only be consumed once, but they do make sense in many situations also in hdom. It all really depends on how your components are setup/created.

  1. This will FAIL after first render:
start(["ul", tx.map((i) => ["li", i], tx.range(5))]);

The reason this fails is because the value passed to start() is the array ["ul", iterator], but then the iterator can only be consumed once... hence in the second frame the ul element will have no more children and so they'll be diffed away.

  1. This WORKS:
start(["ul", ...tx.map((i) => ["li", i], tx.range(5))]);

Here the spread operator forces the iterator to be realized before the array is passed to start(), so the array is really now a static piece of data ["ul", ["li", 0], ["li", 1], ....]

  1. This WORKS too:
start(()=> ["ul", tx.map((i) => ["li", i], tx.range(5))]);

Here the value passed to start is a function which will be re-executed every single time, so works too...

Hope that clears things up!

@den1k
Copy link
Author

den1k commented Sep 11, 2018

It does! Thanks @postspectacular !

@den1k den1k closed this as completed Sep 11, 2018
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