Reactで余分な<div>のラッピングを回避するにはどうすればよいですか?


113

今日、私はReactJSの学習を開始し、1時間後に問題に直面しました。ページのdiv内に2つの行を持つコンポーネントを挿入したいと思います。

私はhtmlを持っています:

<html>
..
  <div id="component-placeholder"></div>
..
</html>

このようなレンダリング関数:

...
render: function() {

    return(
        <div className="DeadSimpleComponent">
            <div className="DeadSimpleComponent__time">10:23:12</div >
            <div className="DeadSimpleComponent__date">MONDAY, 2 MARCH 2015</div>
        </div>
    )
}
....

そして以下ではレンダーと呼んでいます:

ReactDOM.render(<DeadSimpleComponent/>, document.getElementById('component-placeholder'));

生成されたHTMLは次のようになります。

<html>
..
  <div id="component-placeholder">
    <div class="DeadSimpleComponent">
            <div class="DeadSimpleComponent__time">10:23:12</div>
            <div class="DeadSimpleComponent__date">MONDAY, 2 MARCH 2015</div>
    </div>
</div>
..
</html>

Reactがすべてを "DeadSimpleComponent"のdivでラップすることを強いられているので、私はあまり満足していません。明示的なDOM操作なしで、そのための最善かつ簡単な回避策は何ですか?

更新7/28/2017:ReactのメンテナーがReact 16 Beta 1でその可能性を追加しました

React 16.2以降、これを行うことができます:

render() {
  return (
    <>
      <ChildA />
      <ChildB />
      <ChildC />
    </>
  );
}

4
完璧な命名の練習;-)
Kirill Reznikov '17

HTMLファイルを見せてもらえますか?私はあなたの質問を読み間違えました。ただし、回避策があるかもしれません。
Louis93、2015年


単一の要素を持つコンポーネントに問題がありますか?本当に?
ドミニク、

どういう意味ですか?私はReactを試しているだけですが、それほど複雑ではないはずです。しかし、制限は厄介に見えます。
キリルReznikov 2015年

回答:


142

この要件は、Reactバージョン(16.0)] 1で削除されたため、このラッパーを回避できるようになりました。

React.Fragmentを使用して、親ノードを作成せずに要素のリストをレンダリングできます(公式の例)。

render() {
  return (
    <React.Fragment>
      <ChildA />
      <ChildB />
      <ChildC />
    </React.Fragment>
  );
}

詳細:フラグメント


1
素晴らしいニュースDmitryUlyanets。発売予定日はありますか?
Jonas Carlbaum 2017年

2017年9月26日以降にリリースされました。reactjs.org/ blog / 2017/09/26 / react
Tom

56

2017-12-05更新: React v16.2.0がフラグメントのレンダリングを完全にサポートするようになり、子のキーを指定せずにコンポーネントのrenderメソッドから複数の子を返すサポートが改善されました。

render() {
  return (
    <>
      <ChildA />
      <ChildB />
      <ChildC />
    </>
  );
}

v16.2.0より前のReactバージョンを使用している場合は、<React.Fragment>...</React.Fragment>代わりに使用することもできます。

render() {
  return (
    <React.Fragment>
      <ChildA />
      <ChildB />
      <ChildC />
    </React.Fragment>
  );
}

元の:

React v16.0では、divでラップせずにrenderメソッドで要素の配列を返すようになりました:https ://reactjs.org/blog/2017/09/26/react-v16.0.html

render() {
  // No need to wrap list items in an extra element!
  return [
    // Don't forget the keys :)
    <li key="A">First item</li>,
    <li key="B">Second item</li>,
    <li key="C">Third item</li>,
  ];
}

現時点では、キー警告を回避するために各要素にキーが必要ですが、これは将来のリリースで変更される可能性があります。

将来的には、キーを必要としない特別なフラグメント構文をJSXに追加する予定です。


<> </>の新しい省略構文は素晴らしいです。しかし、私はまだそれについて多くの混合感を持っています。
Thulani Chivandikwa

@ThulaniChivandikwa省略構文についての不安を表明してもよろしいですか?
トム・

1
空のタグがJSXで奇妙であり、それが何をするのかを正確に理解していない限り、あまり直感的ではないという概念に関するものだと思います。
Thulani Chivandikwa


3

()の代わりに[]を使用して、戻り値全体をラップします。

render: function() {
  return[
    <div className="DeadSimpleComponent__time">10:23:12</div >
    <div className="DeadSimpleComponent__date">MONDAY, 2 MARCH 2015</div>
  ]
}


1

これはまだ必要とされしかし 今リアクト追加のDOM要素を作成せずに要素を作成してください。

余分なラッピング(通常は親に必要なdiv)反応するためcreateElementの方法は、必要typeなパラメータをeither a tag name string (such as 'div' or 'span'), a React component type (a class or a function)。しかし、これは彼らがReactを導入する前でしたFragmentでした。

createElementについては、この新しいAPIドキュメントを参照してください

React.createElement:指定されたタイプの新しいReact要素を作成して返します。type引数は、タグ名文字列( 'div'や 'span'など)、Reactコンポーネントタイプ(クラスまたは関数)、またはReactフラグメントタイプのいずれかです。

これが公式の例です。React.Fragmentを参照してください。

render() {
  return (
    <React.Fragment>
      Some text.
      <h2>A heading</h2>
    </React.Fragment>
  );
}

0

そのdiv要素を取り除くことはできません。React.render()は1つの有効なDOMノードを返す必要があります。


divは無視され、Knockout.JSは同じことを行います。コンポーネントの外側にスタイルを設定しないdivを指定しても、何の影響もありません。
Chris Hawkes、2015年

16
@ChrisHawkes、同意しない。1つのラッパーdivがcssセレクターに影響します。
ダウンヒル

完全にReactコンポーネントになりたくないという意味の要素を扱う場合、これは問題になります。ヘッダー要素とフッター要素を持つセクションタグがあり、その間にReact内で使用したくないGoogleマップコンテナーがあるとします。次に、Reactコンポーネントとしてヘッダーを追加し、Reactコンポーネントとしてフッターを追加することなく、Reactコンポーネントの内側に追加のdiv:sを含める必要はありません。 you output ...
Jonas Carlbaum 2017年

0

「透明な」コンポーネントをレンダリングする1つの方法を次に示します。

import React from 'react'

const Show = (props) => {
  if (props.if || false) {
    return (<React.Fragment>{props.children}</React.Fragment>)
  }
  return '';
};

----


<Show if={yomama.so.biq}>
    <img src="https://yomama.so.biq">
    <h3>Yoamama</h3>
<Show>

ここに画像の説明を入力してください


0

回避策もあります。以下のブロックコードは、React.Fragmentを必要とせずにフラグメントを生成します。

return [1,2,3].map(i=>{
if(i===1) return <div key={i}>First item</div>
if(i===2) return <div key={i}>Second item</div>
return <div key={i}>Third item</div>
})

0

私はこの質問に答えていることを知っています。もちろん、ノードを作成しないReact.Fragmentを使用できますが、divのようなものをグループ化しましょう。

さらに、楽しみたい場合は、余分なdivを削除するReactモードを実装(および多くのことを学ぶ)できます。これについては、reactコードベース自体でそれを行う方法に関する素晴らしいビデオを共有したいと思います。

https://www.youtube.com/watch?v=aS41Y_eyNrU

これはもちろん実際に行うことではありませんが、良い学習の機会です。

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