2017-02-25 29 views
3

タグをレンダリングするコンポーネントがあります。マップをループしてデータを表示します。私はforEachを使って試しましたが、うまくいきません。しかし、マップを配列に変換すると(foreachは配列でも動作しません)、それが動作します。私はここで何が欠けていますか?jsコンポーネントが反応し、マップが動作し、foreachが反応しない

この作品:

render(){ 
    return(
     <div class="container"> 
      {Array.from(this.props.tags.values()).map((tag,i) => (
       <Tag 
        handleKeyDown={this.handleKeyDown.bind(this)} 
        handleBlur={this.handleBlur.bind(this)} 
        handleTouchTap={this.handleTouchTap.bind(this)} 
        handleRequestDelete={this.handleRequestDelete.bind(this)} 
        tag={tag} 
        key={i} 
       /> 
      ))} 
     </div> 
    ) 
} 

これはしません:

render(){ 
    return(
     <div class="container"> 
      {this.props.tags.forEach((tag,i) => (
       <Tag 
        handleKeyDown={this.handleKeyDown.bind(this)} 
        handleBlur={this.handleBlur.bind(this)} 
        handleTouchTap={this.handleTouchTap.bind(this)} 
        handleRequestDelete={this.handleRequestDelete.bind(this)} 
        tag={tag} 
        key={i} 
       /> 
      ))} 
     </div> 
    ) 
} 

答えて

1

Map#forEachは、新しい配列を返しません。それらは両方ともあなたが予期していた通り正確に動作します。これはArray#mapが古い配列からマッピングされた新しい配列を構築するためのものです。 React.createElementは、その子を引数リストとして、または配列としてとる必要があります。一般的にはMapというよりも平文のほうが配列の方が良いと思っています。つまり、その値を別に管理したい場合は配列に変換します。

あなたのArray.fromの使用は良いアプローチです。これは通常私がMapを使用する方法です。あなたが本当にそれを使って近代的になりたいのであれば、反復の1つを避けたいのですが(もっとも極端な場合には問題はないと思いますが)、イテレータ関数をマップの値に適用してから、イテレータ。

render() { 
    const asTags = function*() { 
    for (const [key, tag] of this.props.tags) { 
     yield <Tag tag={tag} key={key} />; 
    } 
    }; 

    return (
    <div class="container"> 
     {[...asTags()]} 
    </div> 
); 
} 

ジェネレータ関数は、それがあなたの地図に貫通ループyieldのエントリの各単純イテレータ、です。 JSXの中で引数を広げる方法(私がJSXを使用しない理由の1つ)を完全にはわからないので、私はそこで配列を使います。 React.createElementceとしてインポートした場合は、代わりにレンダーでce('div', { class: 'container' }, ...asTags())と言うことができます。

+0

ありがとうございます!マップを配列に変換し、そのマップを使用する以外の方法がありますか? – Gopid

+0

確かに@Gopid、私はジェネレータを使った例で答えを更新しました。これは、一度配列に変換する必要がなくなり、エントリを新しいフォーマットに直接反復してマップすることができます。 –

関連する問題