web-dev-qa-db-ja.com

解析エラー:隣接するJSX要素は囲んでいるタグでラップする必要があります

設定した変数がtrueの場合にのみレンダリングされるように、React.jsアプリケーションを設定しようとしています。

私のレンダリング機能の設定方法は次のようになります。

render: function() {
    var text = this.state.submitted ? 'Thank you!  Expect a follow up at '+email+' soon!' : 'Enter your email to request early access:';
    var style = this.state.submitted ? {"backgroundColor": "rgba(26, 188, 156, 0.4)"} : {};
    return (
    <div>

if(this.state.submitted==false) 
{

      <input type="email" className="input_field" onChange={this._updateInputValue} ref="email" value={this.state.email} />

      <ReactCSSTransitionGroup transitionName="example" transitionAppear={true}>
      <div className="button-row">
         <a href="#" className="button" onClick={this.saveAndContinue}>Request Invite</a>
     </div>
     </ReactCSSTransitionGroup>
}
   </div>
    )
  },

基本的に、ここで重要なのはif(this.state.submitted == false)の部分です(送信された変数がfalseに設定されているときにこれらのdivが表示されるようにします)。

しかし、これを実行すると、質問にエラーが表示されます。

捕捉されないエラー:解析エラー:38行目:隣接するJSX要素は囲んでいるタグでラップされている必要があります

ここで問題は何ですか?そして私はこれを機能させるために何を使うことができますか?

352
user1072337

コンポーネントを囲むタグで囲む必要があります。つまり、

// WRONG!

return (  
    <Comp1 />
    <Comp2 />
)

代わりに:

// Correct

return (
    <div>
       <Comp1 />
       <Comp2 />
    </div>
)

編集: Per Joe Clayの Fragments APIについてのコメント

// More Correct

return (
    <React.Fragment>
       <Comp1 />
       <Comp2 />
    </React.Fragment>
)
514
wdanxna

反応要素は1つの要素だけを返す必要があります。両方のタグを別の要素タグでラップする必要があります。

また、あなたのレンダリング関数が何も返していないこともわかります。これがコンポーネントの外観です。

var app = React.createClass({
    render () {
        /*React element can only return one element*/
        return (
             <div></div>
        )
    }
})

また、返された要素の中でifステートメントを使用することはできません。

render: function() {
var text = this.state.submitted ? 'Thank you!  Expect a follow up at '+email+' soon!' : 'Enter your email to request early access:';
var style = this.state.submitted ? {"backgroundColor": "rgba(26, 188, 156, 0.4)"} : {};
    if(this.state.submitted==false) {
        return <YourJSX />
    } else {
        return <YourOtherJSX />
    }
},
103
Matan Gubkin

他の答えで示唆されているように他のdivにラップしたくない場合は、それを配列にラップしても機能します。

// Wrong!
return (  
   <Comp1 />
   <Comp2 />
)

次のように書くことができます。

// Correct!
return (  
    [<Comp1 />,
    <Comp2 />]
)

上記は警告を生成することに注意してください:Warning: Each child in an array or iterator should have a unique "key" prop. Check the render method of 'YourComponent'.

これを手動で追加する場合、コンポーネントにkey属性を追加することで修正できます。

return (  
    [<Comp1 key="0" />,
    <Comp2 key="1" />]
)

これがキーに関するいくつかのより多くの情報です: http://facebook.github.io/react/docs/multiple-components.html#dynamic-children

83
Neal

問題

解析エラー:隣接するJSX要素は囲んでいるタグでラップする必要があります

これは、誤った方法で複数の兄弟JSX要素を返そうとしていることを意味します。あなたはHTMLではなくJSXを書いていることを覚えておいてください。あなたのコードはJSXからJavaScriptに変換されます。例えば:

render() {
  return (<p>foo bar</p>);
}

次のように書き換えられます:

render() {
  return React.createElement("p", null, "foo bar");
}

一般的なプログラミングに慣れていない限り、(任意の言語の)関数/メソッドが任意の数のパラメータを受け取ることを既に知っていますが、常にone valueのみを返します。それを考えれば、createElement()がどのように機能するかに基づいて、複数の兄弟コンポーネントを返そうとすると問題が発生することがおそらくわかります。 one elementのパラメータだけを取り、それを返します。したがって、1つの関数呼び出しから複数の要素を返すことはできません。


あなたがこれがなぜうまくいくのか疑問に思ったことがあるのであれば...

render() {
  return (
    <div>
      <p>foo</p>
      <p>bar</p>
      <p>baz</p>
    </div>
  );
}

しかしこれではない...

render() {
  return (
    <p>foo</p>
    <p>bar</p>
    <p>baz</p>
  );
}

最初のスニペットでは、両方の<p>-要素が<div>-要素のchildrenの一部であるためです。それらがchildrenの一部であるときは、無制限の数の兄弟要素を表現することができます。これがどのように置き換えられるかを見てみましょう。

render() {
  return React.createElement(
    "div",
    null,
    React.createElement("p", null, "foo"),
    React.createElement("p", null, "bar"),
    React.createElement("p", null, "baz"),
  );
}

ソリューション

実行しているReactのバージョンに応じて、これに対処するためのいくつかのオプションがあります。

  • フラグメントを使う(React v16.2以降のみ)

    React v16.2から、Reactは子を直接返すノードレスコンポーネントであるFragmentsをサポートしています。

    子を配列で返す(下記参照)にはいくつかの欠点があります。

    • 配列内の子はコンマで区切る必要があります。
    • アレイの子供たちはReactの重要な警告を防ぐための鍵を持っていなければなりません。
    • 文字列は引用符で囲む必要があります。

    これらはフラグメントの使用から排除されています。これは、フラグメントに包まれた子の例です。

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

    これは、次のようになります。

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

    最初のスニペットにはBabel v7.0以降が必要です。


  • 配列を返します(React v16.0以降のみ)。

    React v16以降、React Componentsは配列を返すことができます。これは、すべての兄弟コンポーネントを親コンポーネントでラップすることを余儀なくされた以前のバージョンのReactとは異なります。

    言い換えれば、あなたは今することができます:

    render() {
      return [<p key={0}>foo</p>, <p key={1}>bar</p>];
    }
    

    これは次のようになります。

    return [React.createElement("p", {key: 0}, "foo"), React.createElement("p", {key: 1}, "bar")];
    

    上記は配列を返すことに注意してください。配列はReactバージョン16以降から有効なReact要素です。 Reactの以前のバージョンでは、配列は有効な戻りオブジェクトではありません。

    以下は invalid です(配列を返さなければなりません):

    render() {
      return (<p>foo</p> <p>bar</p>);
    }
    

  • 要素を親要素にラップする

    もう1つの解決策は、兄弟コンポーネントをそのchildrenにラップする親コンポーネントを作成することです。これは、この問題に対処するための最も一般的な方法であり、Reactのすべてのバージョンで機能します。

    render() {
      return (
        <div>
          <h1>foo</h1>
          <h2>bar</h2>
        </div>
      );
    }
    

    注:この回答の冒頭で詳細を確認し、この転記の仕方をもう一度見てください

48
Chris

React 16.0.0 renderから複数のコンポーネントを配列として返すことができます。

return ([
    <Comp1 />,
    <Comp2 />
]);

React 16.4.0 Fragmentタグでrenderから複数のコンポーネントを返すことができます。 フラグメント

return (
<React.Fragment>
    <Comp1 />
    <Comp2 />
</React.Fragment>);

将来の反応 あなたはこの速記法を使うことができるでしょう。 (多くのツールではまだサポートされていないので、ツールが追いつくまで明示的に<Fragment>を書くことをお勧めします。)

return (
<>
    <Comp1 />
    <Comp2 />
</>)
21
Morris S

あなたがあなたのコンポーネントをラップしないなら、あなたは以下の方法で述べられるようにそれを書くことができます。

の代わりに:

return(
  <Comp1 />
  <Comp2 />
     );

あなたはこれを書くことができます:

return[(
 <Comp1 />
),
(
<Comp2 />
) ];
4
ronak ganatra

JSX式は最も外側の要素を1つだけ持つ必要があるという反応の規則があります。

違う

const para = (
    <p></p>
    <p></p>
);

正しい

const para = (
    <div>
        <p></p>
        <p></p>
    </div>
);
2

リアクトコンポーネントは単一のコンテナでラッピングする必要があります。これは任意のタグ例: "<div> .. </ div>"にすることができます

ReactCSSTransitionGroupのレンダリング方法を確認できます

2
Shivprasad P

React 16は戻り値を配列として取得するので、divのように1つの要素でラップする必要があります。

間違ったアプローチ

render(){
    return(
    <input type="text" value="" onChange={this.handleChange} />

     <button className="btn btn-primary" onClick=   {()=>this.addTodo(this.state.value)}>Submit</button>

    );
}

Right Approach(1つのdiv内のすべての要素、または使用している他の要素)

render(){
    return(
        <div>
            <input type="text" value="" onChange={this.handleChange} />

            <button className="btn btn-primary" onClick={()=>this.addTodo(this.state.value)}>Submit</button>
        </div>
    );
}
2
Abdul Moiz

無効: 子要素だけでなく

render(){
        return(
            <h2>Responsive Form</h2>
            <div>Adjacent JSX elements must be wrapped in an enclosing tag</div>
            <div className="col-sm-4 offset-sm-4">
                <form id="contact-form" onSubmit={this.handleSubmit.bind(this)} method="POST">
                    <div className="form-group">
                        <label for="name">Name</label>
                        <input type="text" className="form-control" id="name" />
                    </div>
                    <div className="form-group">
                        <label for="exampleInputEmail1">Email address</label>
                        <input type="email" className="form-control" id="email" aria-describedby="emailHelp" />
                    </div>
                    <div className="form-group">
                        <label for="message">Message</label>
                        <textarea className="form-control" rows="5" id="message"></textarea>
                    </div>
                    <button type="submit" className="btn btn-primary">Submit</button>
                </form>
            </div>
        )
    }

有効: 子要素の下のルート要素

render(){
        return(
          <div>
            <h2>Responsive Form</h2>
            <div>Adjacent JSX elements must be wrapped in an enclosing tag</div>
            <div className="col-sm-4 offset-sm-4">
                <form id="contact-form" onSubmit={this.handleSubmit.bind(this)} method="POST">
                    <div className="form-group">
                        <label for="name">Name</label>
                        <input type="text" className="form-control" id="name" />
                    </div>
                    <div className="form-group">
                        <label for="exampleInputEmail1">Email address</label>
                        <input type="email" className="form-control" id="email" aria-describedby="emailHelp" />
                    </div>
                    <div className="form-group">
                        <label for="message">Message</label>
                        <textarea className="form-control" rows="5" id="message"></textarea>
                    </div>
                    <button type="submit" className="btn btn-primary">Submit</button>
                </form>
            </div>
          </div>
        )
    }
1
KARTHIKEYAN.A

ビューをインポートしてViewにラップします。 divにラップすることは私にとってうまくいきませんでした。

import { View } from 'react-native';
...
    render() {
      return (
        <View>
          <h1>foo</h1>
          <h2>bar</h2>
        </View>
      );
    }
1
Ocko

Rect-Native開発者向け。 FlatListでアイテムをレンダリングしているときにこのエラーが発生します。 2つのテキストコンポーネントがありました。私は以下のようにそれらを使用していました

renderItem = { ({item}) => 
     <Text style = {styles.item}>{item.key}</Text>
     <Text style = {styles.item}>{item.user}</Text>
}

しかし、これらの内部ビューコンポーネントを配置した後、私にとってはうまくいきました。

renderItem = { ({item}) => 
   <View style={styles.flatview}>
      <Text style = {styles.item}>{item.key}</Text>
      <Text style = {styles.item}>{item.user}</Text>
   </View>
 }

他のコンポーネントを使用している可能性がありますが、それらをViewに入れることはうまくいくかもしれません。

0
GSK

非常に簡単です。親要素divを使用してすべての要素をラップすることも、高次コンポーネント(HOC)の概念を使用することもできます。つまり、react jsアプリケーションに非常に役立ちます

render() {
  return (
    <div>
      <div>foo</div>
      <div>bar</div>
    </div>
  );
}

あるいは、もう1つの最善の方法は、HOCです。プロジェクトにhoc.jsファイルを追加して、単にこれらのコードを追加するだけです。

const aux = (props) => props.children;
export default aux;

使用したい場所にhoc.jsファイルをインポートします。今度はdiv要素でラップする代わりに、hocでラップできます。

import React, { Component } from 'react';
import Hoc from '../../../hoc';

    render() {
      return (
    <Hoc>
        <div>foo</div>
        <div>bar</div>
    </Hoc>
      );
    }
0
Fazal