親タグでラップせずに兄弟要素をレンダリングするにはどうすればよいですか?


82

ほとんどの場合、親タグを持つことは問題ではありません。

React.createClass({
    render: function() {
        return (
            <tbody>
                <tr><td>Item 1</td></tr>
                <tr><td>Item 2</td></tr>
            </tbody>
        );
    }
});

ただし、親なしで1つのレンダリング関数に兄弟要素を含めることが理にかなっている場合があります。特にテーブルの場合は、テーブルの行をでラップしたくない場合がありますdiv

React.createClass({
    render: function() {
        return (
            <tr><td>Item 1</td></tr>
            <tr><td>Item 2</td></tr>
        );
    }
});

2番目の例では、次のエラーが発生しますAdjacent XJS elements must be wrapped in an enclosing tag while parsing file

2つの兄弟要素を、<div>または同様のものでラップせずにレンダリングするにはどうすればよいですか?


3
私はいつもこの質問/回答を見つけるのに苦労しているようですので、自分で質問/回答することにしました。追加の説明/回答は大歓迎です。
thealexbaron 2015

別の例はナビゲーションアイテムです
Tjorriemorrie 2016年

回答:


66

これは現在の制限ですが、将来のある時点で修正される可能性があります(githubリポジトリにいくつかの未解決の問題があります)。

今のところ、配列を返す関数を使用できます(これは基本的にステートレスコンポーネントです)。

function things(arg, onWhatever){
    return [
        <tr><td>Item 1</td></tr>,
        <tr><td>Item 2</td></tr>
    ];
}

そして、それをコンポーネントで使用します。

return (
    <table><tbody>
      {things(arg1, this.handleWhatever)}
      {things(arg2, this.handleWhatever)}
    </tbody></table>
);

更新

React 16では、レンダリングから配列を返すことができます。

別の更新

これで、最上位の配列を返すか、を使用できます <React.Fragment>

配列では、動的に作成されたリストではなく、Reactが2つの要素が定数であることを認識しないため、各アイテムにキーを配置する必要があります。

function RowPair() {
  return [
    <tr key="first"><td>First</td></tr>,
    <tr key="second"><td>Second</td></tr>,
  ]
}

を使用React.Fragmentすると、<div>または同様のものでラップするように動作しkeyます。子を動的に構築しない場合は、aは必要ありません。まず、配列をフラグメントでラップできます。

function RowPair() {
  return <React.Fragment>{[
    <tr key="first"><td>First</td></tr>,
    <tr key="second"><td>Second</td></tr>,
  ]}</React.Fragment>
}

そして、配列とkeysを完全に削除できます。

function RowPair() {
  return <React.Fragment>
    <tr><td>First</td></tr>
    <tr><td>Second</td></tr>
  </React.Fragment>
}

2
なぜ誰もがこれがうまくいくと言うのですか???? キャッチされないエラー:x.render():有効なReact要素(またはnull)を返す必要があります。未定義、配列、またはその他の無効なオブジェクトを返した可能性があります。
xogle 2016

@Xogle ReactAPIで何かが変更されている必要があります。もう動作していないようです。
Petr Peller 2017年

1
@FakeRainBrigand問題が発生しました。これは「ステートレスコンポーネント」ではなく、配列を返す関数です。ステートレスコンポーネントは配列を返すことができず、単純な関数をReduxストアに接続することはできません。
Petr Peller 2017年

@PetrPellerはjsxを使用していますか?この例では、関数のように呼び出しています。
山賊2017年

私はすべての賛成票を理解していません-これは質問にまったく答えません。問題は、親要素なしで兄弟要素をレンダリングする方法ですが、この答えは依然として親要素をレンダリングします。
ダンクラム

33

これが古い投稿であることは知っていますが、私の答えは私のような初心者の助けになるかもしれません。

React 16.2では、フラグメントのサポートが改善されました。

これで、次のように返すことができます。

return (
  <>
    <tr><td>Item 1</td></tr>
    <tr><td>Item 2</td></tr>
  </>
);

<></>またはでラップでき<Fragment></Fragment>ます。

一部の属性を渡したい場合は、執筆時点ではキーのみがサポートされて<Fragment />おり、短い構文なので使用する必要があります。<></>は属性を受け入れないます。

注:短い構文を使用する場合は、 使用していることを確認してくださいバベル7

ソースリファレンス


1
まさに私が求めていたもの、ありがとう!また、他の誰かがそれを必要とする場合に備えて:import React、{Fragment}
Chris

Fragmentリポジトリでの実装が見つからないようです。誰かに見せてもらえますか?ありがとう:)
Ramon Balthazar 2018年

Babel-cliをインストールしても動作させることができません... <>ソリューションの場合でも。どのようにそれは、私はすぐにスレッドを掲載する予定だ可能@onoyaある
Gaelle


3

親要素を持つことは、ほとんどの場合に役立ちます。たとえば、親classNameを持つことができます。子要素のスタイルやその他のいくつかのシナリオをターゲットにできるを持つことができます...

しかし、本当にそれをしたくない場合は、使用することができます React.Fragment

したがって、次のようなことを行うだけです。

<React.Fragment>
  <First />
  <Second />
  <Third />
</React.Fragment>

バージョン16.2から<>、レンダリング関数で次のように見える、も使用する短縮バージョンがあります。

render() {
  return (
    <>
      <First />
      <Second />
      <Third />
    </>
  );
}

また、バージョン16.0以降を使用している場合は、以下のように、親ラッパーを必要としない要素の配列を返すことができます。

render() {
 return [
  <h1 key="heading">Hello from Alireza!</h1>,
  <p key="first">Here where I'm!</p>,
  <p key="second">And again here :)</p>
 ];
}

0

次のように角かっこで囲むことができます。

React.createClass({
    render: function() {
        return (
          [
            <tr><td>Item 1</td></tr>
            <tr><td>Item 2</td></tr>
          ]
        );
    }
});

Object.keys()返品の際にも使用する必要がある場合はどうですか?
Juha Untinen 2017

例えば。 return ( [ <tr><td>Header</td></tr>{ Object.keys(this.props.data).map(function(item) { <tr><td>{data}</td></tr> }) } ] ); 15.4.2ではUnexpected token, expected ,、リターン内の開始ブラケットを示します
Juha Untinen 2017

次のようなものを試してください:return({Object.keys(this.props.data).map(function(item){<tr> <td> {data} </ td> </ tr>})。unshift({< tr> <td>ヘッダー</ td> </ tr>})});
Vitaliy Andrusishyn 2017

これは機能しませんが、<tr> -sを区切るコンマが必要です
Philipp Munin 2017

0

この例は私にとってうまく機能します:

let values = [];

if (props.Values){
  values = [
    <tr key={1}>
      <td>props.Values[0].SomeValue</td>
    </tr>
  ,
    <tr key={2}>
        <td>props.Values[1].SomeValue</td>
        </tr>
    ];
}

return (
    <table className="no-border-table table">
      <tbody>
        <tr>
            <th>Some text</th>
        </tr>
        {values}
      </tbody>
    </table>
)

0

この構文のようなものが私のために働いた

this.props.map((data,index)=>{return( [ <tr>....</tr>,<tr>....</tr>];)});

-2

TypeScriptを使用する人にとって、正しい構文は次のとおりです。

return [
  (
    <div>Foo</div>
  ),
  (
    <div>Bar</div>
  )
];

1
これは@thealexbaronによる回答と同じであり、TypeScriptとは何の関係もありません
andrewarchi 2018年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.