Skip to content

Accept iterables and collections as children. #2296

Closed

Description

@leebyron

React currently accepts Arrays as children:

var array = [<span />, <span />, <span />];
<div>{spans}</div>

It would be excellent if we can generalize this concept to accept both collections and iterables.

Collections (such as Set, Map, or Immutable-js's variants) can be identified if they implement values() and the result of calling values() is an Iterator (typeof maybeIterator.next === 'function').

Iterables (Array, arguments object, other array-ish things, third-party data structures) can be identified if they have Symbol.iterator or @@iterator returning an Iterator.

In both cases, you're left with an Iterator, at which point extracting the children becomes straight-forward.

This unlocks a few really useful things:

Use Immutable-js with React efficiently:

var data = Immutable.Vector('a', 'b', 'c');
<div>{data.map(str => <span>{str.toUpperCase}</span>)}</div>

Use generators:

var data = function*() {
  yield <span />;
  yield <span />;
  yield <span />;
}
<div>{data}</div>

Activity

  1. self-assigned this
    on Oct 6, 2014
  2. leebyron commented on Oct 6, 2014

    @leebyron
    ContributorAuthor
  3. sebmarkbage commented on Oct 6, 2014

    @sebmarkbage
    Contributor

    I'm not sure about the Collections duck typing. Set also have @@iterator so that should be enough.

    Maps are special in that we'd probably want to use the key as the React key value. So we could either detect maps specifically, or just allow any iterable with a sequence of two value tuples. The difficult part is, how do you determine if the tuple is a nested array value or Map tuple?

  4. leebyron commented on Oct 6, 2014

    @leebyron
    ContributorAuthor

    Maybe Iterable is enough then.

    Map iterators return tuples while Set and Array iterators return individual values. Perhaps we can hold this convention and treat tuple[0] as React key.

  5. leebyron commented on Oct 6, 2014

    @leebyron
    ContributorAuthor

    The drawback with that is nested iterables/arrays. Explicitly looking for a method spec'd for Collections (entries if we also want to see keys) would differentiate the cases

  6. syranide commented on Oct 7, 2014

    @syranide
    Contributor

    Perhaps I misunderstood the discussion, but it seems to me that you must explicitly test for Map vs Set, etc. A Set containing tuples should not be interpreted as key/value, as it's not unthinkable that you would want store lists of children in a Set.

    PS. IE11 collections does not have iterator, @@iterator nor values, etc.

  7. leebyron commented on Oct 21, 2014

    @leebyron
    ContributorAuthor

    #2376 implements this.

    IE11 collections are a mess. I think the right strategy is to intelligently check for a native ES6 Map/Set implementation and polyfill over them if they are non-compliant. This is the approach we're taking at Facebook.

  8. syranide commented on Oct 23, 2014

    @syranide
    Contributor

    @leebyron Sounds sane, "we" could even polyfill Array to be a cheap iterable very easily as well. As for IE11, I believe I showed you my earlier work on back-porting Map and Set (and an approximate WeakMap and WeakSet as well) to all legacy browsers which actually perform rather well (both perf and memory). Those could easily be made smart enough to use IE11 Map/Set as the underlying data structure and just provide the additional data required for fast ordered iteration.

  9. graue commented on Nov 14, 2014

    @graue
    Contributor

    @leebyron Should this be closed now that #2376 is merged?

  10. leebyron commented on Nov 14, 2014

    @leebyron
    ContributorAuthor

    Yep, thanks for the reminder :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions