マップするオブジェクトの配列なしでReact.jsの要素をループしてレンダリングする方法は?


145

jQueryコンポーネントをReact.jsに変換しようとしていますが、問題の1つはforループに基づいてn個の要素をレンダリングすることです。

これは不可能であるか、または推奨されておらず、モデルに配列が存在する場合、それを使用することは完全に理にかなっていることを理解していますmap。それは問題ありませんが、配列がない場合はどうでしょうか?代わりに、レンダリングする要素の数に等しい数値がある場合、どうすればよいですか?

これが私の例です。階層レベルに基づいて、要素の前に任意の数のスパンタグを付けたいと思います。したがって、レベル3では、テキスト要素の前に3つのスパンタグが必要です。

JavaScriptでは:

for (var i = 0; i < level; i++) {
    $el.append('<span class="indent"></span>');
}
$el.append('Some text value');

これ、またはJSX React.jsコンポーネントで動作するようなものを取得できないようです。代わりに、以下を実行する必要がありました。最初に一時配列を正しい長さに構築し、次に配列をループしました。

React.js

render: function() {
  var tmp = [];
  for (var i = 0; i < this.props.level; i++) {
    tmp.push(i);
  }
  var indents = tmp.map(function (i) {
    return (
      <span className='indent'></span>
    );
  });

  return (
    ...
    {indents}
    "Some text value"
    ...
  );
}

確かに、これは最善の方法ではありませんか、またはこれを達成する唯一の方法ですか?何が欠けていますか?



:また、あなただけのことを行うことができjsfiddle.net/crl/69z2wepo/19804
caub

回答:


241

更新:React> 0.16現在

Renderメソッドは必ずしも単一の要素を返す必要はありません。配列を返すこともできます。

var indents = [];
for (var i = 0; i < this.props.level; i++) {
  indents.push(<span className='indent' key={i}></span>);
}
return indents;

または

return this.props.level.map((item, index) => (
    <span className="indent" key={index}>
        {index}
    </span>
));

JSXの子供について説明しているドキュメント


古い:

代わりに1つのループを使用できます

var indents = [];
for (var i = 0; i < this.props.level; i++) {
  indents.push(<span className='indent' key={i}></span>);
}
return (
   <div>
    {indents}
    "Some text value"
   </div>
);

.mapとfancy es6 も使用できます

return (
   <div>
    {this.props.level.map((item, index) => (
       <span className='indent' key={index} />
    ))}
    "Some text value"
   </div>
);

また、戻り値をコンテナでラップする必要があります。上記の例ではdivを使用しました

ドキュメントがここで言うよう

現在、コンポーネントのレンダーでは、1つのノードのみを返すことができます。たとえば、返すdivのリストがある場合は、div、span、またはその他のコンポーネント内でコンポーネントをラップする必要があります。


1
これでうまくいき、おかげでもっと簡単になりました。はい、私はあなたがコンテナに戻り値をラップする必要があることを承知しています、私はすでにそれをしているだけです、それは例からただ欠けています。
ジョナサンマイル

2
ループ内にキーを追加します。鍵は反応で重要です。
アーミルアフリディ2016年

4
私は一生あなたのことをずっとずっと探していました
olleh

2
@ElgsQianChenそれは不可能です。いくつかのタグでラップする必要があります。{indents}がコンテンツを含む単一のdom要素を返す場合、
問題ありません

2
mapメソッドがArrayオブジェクトに対してのみ機能するため、この回答でなぜmapメソッドが言及されているのか理解できません。質問には明らかにそうではありません。
flukyspore

47

ES6の機能を備えたより機能的な例を次に示します。

'use strict';

const React = require('react');

function renderArticles(articles) {
    if (articles.length > 0) {      
        return articles.map((article, index) => (
            <Article key={index} article={article} />
        ));
    }
    else return [];
}

const Article = ({article}) => {
    return ( 
        <article key={article.id}>
            <a href={article.link}>{article.title}</a>
            <p>{article.description}</p>
        </article>
    );
};

const Articles = React.createClass({
    render() {
        const articles = renderArticles(this.props.articles);

        return (
            <section>
                { articles }
            </section>
        );
    }
});

module.exports = Articles;

1
これは、最も「Reacty」な方法のように見えます。値を小道具として別のサブコンポーネントに渡します。ありがとう!
Michael Giovanni Pumo

これは素晴らしいです!render()がHTMLに重い場合に最適です。
マシュー2017年

それはより多くのES6はあなたが使用できるようにするにimport React from "react"してexport default Articles
jonlink

1
この答えは質問に答えようとさえしません。for loopアイテムの配列を持たずにReactコンポーネントでn個のアイテムをレンダリングするために、マップ可能な配列(またはオブジェクト)にどのように変換するかという質問は明白でした。あなたの解決策はその事実を完全に無視し、小道具からの記事の配列を渡されると想定しています。
ジョナサンマイル

17

Object.keys(chars).map(...)レンダーのループに使用しています

// chars = {a:true, b:false, ..., z:false}

render() {
    return (
       <div>
        {chars && Object.keys(chars).map(function(char, idx) {
            return <span key={idx}>{char}</span>;
        }.bind(this))}
        "Some text value"
       </div>
    );
}

あなたの答えは私のために働いたが、私が追加した後にのみchars && ....bind(this)私の関数の終わりに。なぜObject...(など)が機能しないのか、私は興味があります。私は未定義になり続けました。
m00saca 2017

2
これは質問の答えにはなりません。解析するオブジェクトの配列なしで具体的に述べられており、説明では、Reactコンポーネントでレンダリングするためにforループをマップに変換したいと明確に述べています。質問への回答に役立たないオブジェクトを配列に置き換えたか、さらに値を追加しました。
ジョナサンマイル

16

Array.from()反復可能なオブジェクトを取り、配列およびオプションのマップ関数に変換します。.length次のように、プロパティを持つオブジェクトを作成できます。

return Array.from({length: this.props.level}, (item, index) => 
  <span className="indent" key={index}></span>
);

先週これを聞いてたまたま質問を見つけたので、これが私が学んだことを適用する最も速い方法でした!syntax.fm/show/043/...
conradj

1
X個の要素をレンダリングするために必要なものだけです。ありがとうございます。
Liran H

0

これは反応jsでループする最も簡単な方法だと思います

<ul>
    {yourarray.map((item)=><li>{item}</li>)}
</ul>

2
これは質問に対する回答ではありません。回答を試みる前に質問全体を読んでください。
ジョナサンマイル

それは私を助け、私の時間を節約しました。
Ajay Malhotra
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.