joshlevy89
joshlevy89

Reputation: 269

Iterating through keys of Immutable Map in React

What is a good practice for handling iteration through an Immutable.js Map object? This works:

{stocks.map((stock,key)=>{
    return ( <h3>{key}</h3> )
})}

but gives the warning in the console "warning.js:45 Warning: Using Maps as children is not yet fully supported. It is an experimental feature that might be removed. Convert it to a sequence / iterable of keyed ReactElements instead."

This has been discussed before, and this link suggests some strategies https://github.com/facebook/immutable-js/issues/667 but they seem clunky to me. Like:

posts.entrySeq().map(o => 
     <Post value={o[1]} key={o[0]} />
)

works but is clunky feeling. Is there a more natural way of doing this?

Upvotes: 12

Views: 11258

Answers (3)

Muhammad Usman
Muhammad Usman

Reputation: 91

Using Immutable Map's reduce method is a more direct approach. Since react expects an array so setting initial value of empty array and pushing jsx into it solves the issue. Works for immutable List as well.

{
   stocks.reduce((jsxArray, stock, index) => {
      jsxArray.push(
        <h3 key={index}>{index}</h3>,
      )
      return jsxArray;
   }, [])
}

Upvotes: 0

devboell
devboell

Reputation: 1190

Since you asked this question, a better solution has been posted on the github issue you reference. @vinnymac suggests:

posts.entrySeq().map( ([key, value]) => 
  <Post key={key} value={value} />
)

this works well because entrySeq() returns a Sequence of key/value tuples, which you can then destructure in the params of the .map() callback.

edit I see now that you are only asking for the keys. In that case use keySeq() if you want to use ImmutableJS map() or keys() if you want to use ES6 map()

Upvotes: 14

martriay
martriay

Reputation: 5742

Why not stock.keys()? As it returns an ES6 iterator, you'll need to cast it to an array for it to work in older JS versions: Array.from(stock.keys())

let zoo = Immutable.fromJS({ 'dog': 1, 'cat': 2 })

zoo.keys().map((name, index) => <Animal name={ name } key={ index } />)

Notice that I avoided key as a variable and then passed the index value as key to the children component, this is because react needs references to dynamically created components so it can handle them correctly within its VirtualDOM. Read more about React's Dynamic Children.

Upvotes: 2

Related Questions