wake-up-neo.com

Parse Error: Benachbarte JSX-Elemente müssen in ein umschließendes Tag eingeschlossen werden

Ich versuche, meine React.js-App so einzurichten, dass sie nur dann wiedergegeben wird, wenn eine von mir festgelegte Variable wahr ist.

Die Art und Weise, wie meine Renderfunktion eingerichtet ist, sieht folgendermaßen aus:

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>
    )
  },

Grundsätzlich ist der wichtige Teil hier der Teil if (this.state.submitted == false) (ich möchte, dass diese divs angezeigt werden, wenn die übergebene Variable auf false gesetzt ist).

Aber wenn ich das laufen lasse, bekomme ich den Fehler in der Frage:

Nicht erfasster Fehler: Parse Error: Zeile 38: Benachbarte JSX-Elemente müssen in ein umschließendes Tag eingeschlossen werden

Worum geht es hier? Und was kann ich verwenden, um diese Arbeit zu machen?

392
user1072337

Sie sollten Ihre Komponente zwischen ein umschließendes Tag setzen. Das bedeutet:

// WRONG!

return (  
    <Comp1 />
    <Comp2 />
)

Stattdessen:

// Correct

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

Edit: Per Joe Clays Kommentar zur Fragments API

// More Correct

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

Das React-Element muss nur ein Element zurückgeben. Sie müssen beide Tags mit einem anderen Element-Tag umschließen.

Ich kann auch sehen, dass Ihre Renderfunktion nichts zurückgibt. So sollte Ihre Komponente aussehen:

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

Beachten Sie auch, dass Sie if -Anweisungen nicht in einem zurückgegebenen Element verwenden können:

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 />
    }
},
107
Matan Gubkin

Wenn Sie es nicht in ein anderes div packen möchten, wie andere Antworten vorgeschlagen haben, können Sie es auch in ein Array packen, und es wird funktionieren.

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

Es kann geschrieben werden als:

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

Bitte beachten Sie, dass das oben genannte eine Warnung generiert: Warning: Each child in an array or iterator should have a unique "key" prop. Check the render method of 'YourComponent'.

Dies kann behoben werden, indem ein key -Attribut zu den Komponenten hinzugefügt wird. Wenn Sie diese manuell hinzufügen, fügen Sie es folgendermaßen hinzu:

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

Hier einige weitere Informationen zu Schlüsseln: Komposition vs. Vererbung

88
Neal

Das Problem

Parse Error: Benachbarte JSX-Elemente müssen in ein umschließendes Tag eingeschlossen werden

Dies bedeutet, dass Sie versuchen, mehrere geschwisterliche JSX-Elemente auf falsche Weise zurückzugeben. Denken Sie daran, dass Sie nicht HTML, sondern JSX schreiben! Ihr Code wird von JSX in JavaScript übersetzt. Zum Beispiel:

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

wird transpiliert in:

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

Sofern Sie mit dem Programmieren im Allgemeinen nicht vertraut sind, wissen Sie bereits, dass Funktionen/Methoden (in einer beliebigen Sprache) eine beliebige Anzahl von Parametern annehmen, aber immer nur den Wert eins zurückgeben. In Anbetracht dessen können Sie wahrscheinlich feststellen, dass ein Problem auftritt, wenn Sie versuchen, mehrere Geschwisterkomponenten basierend auf der Funktionsweise von createElement() zurückzugeben. Es werden nur Parameter für das one -Element verwendet und diese werden zurückgegeben. Daher können wir nicht mehrere Elemente von einem Funktionsaufruf zurückgeben.


Also, wenn Sie sich jemals gefragt haben, warum das funktioniert ...

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

aber nicht das ...

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

das liegt daran, dass im ersten Snippet beide <p>- Elemente Teil von children des <div>- Elements sind. Wenn sie Teil von children sind, können wir eine unbegrenzte Anzahl von Geschwisterelementen ausdrücken. Schauen Sie sich an, wie sich dies auswirken würde:

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

Lösungen

Abhängig davon, welche Version von React Sie ausführen, haben Sie einige Optionen, um dies zu beheben:

  • Verwenden Sie Fragmente (Reagieren Sie nur mit v16.2 +!)

    Ab React v16.2 unterstützt React Fragmente, eine knotenlose Komponente, die ihre untergeordneten Elemente direkt zurückgibt.

    Das Zurückgeben der untergeordneten Elemente in einem Array (siehe unten) hat einige Nachteile:

    • Kinder in einem Array müssen durch Kommas getrennt werden.
    • Kinder in einem Array müssen einen Schlüssel haben, um Reacts Schlüsselwarnung zu verhindern.
    • Zeichenfolgen müssen in Anführungszeichen gesetzt werden.

    Diese entfallen bei der Verwendung von Fragmenten. Hier ist ein Beispiel für Kinder, die in ein Fragment eingewickelt sind:

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

    die de-Zucker in:

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

    Beachten Sie, dass für das erste Snippet Babel 7.0 oder höher erforderlich ist.


  • Array zurückgeben (nur React v16.0 +!)

    Ab React v16 können React Komponenten Arrays zurückgeben. Dies unterscheidet sich von früheren Versionen von React, in denen Sie gezwungen waren, alle gleichgeordneten Komponenten in eine übergeordnete Komponente einzubinden.

    Mit anderen Worten, Sie können jetzt Folgendes tun:

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

    dies transpiliert in:

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

    Beachten Sie, dass oben ein Array zurückgegeben wird. Arrays sind gültige React Elemente seit React Version 16 und höher. In früheren Versionen von React sind Arrays keine gültigen Rückgabeobjekte!

    Beachten Sie auch, dass Folgendes ngültig ist (Sie müssen ein Array zurückgeben):

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

  • Wickeln Sie die Elemente in ein übergeordnetes Element

    Die andere Lösung besteht darin, eine übergeordnete Komponente zu erstellen, die die gleichgeordneten Komponenten in children einschließt. Dies ist bei weitem die häufigste Methode, um dieses Problem zu beheben, und funktioniert in allen Versionen von React.

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

    Anmerkung: Sehen Sie sich oben in dieser Antwort noch einmal an, um weitere Einzelheiten zu erfahren und zu erfahren, wie diese transpiles.

48
Chris

Reagieren Sie auf 16.0.0 . Wir können mehrere Komponenten vom Rendern als Array zurückgeben.

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

Reagieren Sie auf 16.4.0 . Wir können mehrere Komponenten aus dem Rendern in einem Fragment-Tag zurückgeben. Fragment

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

Future React Sie können diese Kurzschrift verwenden. (Viele Tools unterstützen dies noch nicht. Daher möchten Sie möglicherweise <Fragment> explizit schreiben, bis das Tool aufgeholt hat.)

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

Wenn Sie Ihre Komponente nicht verpacken, können Sie sie wie unten beschrieben schreiben.

Anstatt von:

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

sie können dies schreiben:

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

es ist sehr einfach, dass wir ein übergeordnetes Element div verwenden können, um das gesamte Element zu umbrechen, oder wir können das HOC-Konzept (Higher Order Component) verwenden, das für reaktionsfähige Anwendungen sehr nützlich ist

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

oder eine andere beste Möglichkeit ist HOC. Es ist sehr einfach, nicht sehr kompliziert. Fügen Sie einfach eine Datei hoc.js in Ihr Projekt ein und fügen Sie diese Codes hinzu

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

importieren Sie jetzt die Datei hoc.js, in der Sie sie verwenden möchten. Anstatt mit dem Element div zu arbeiten, können Sie jetzt auch mit hoc arbeiten.

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

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

Es gilt die Regel, dass ein JSX-Ausdruck genau ein äußerstes Element haben muss.

falsch

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

richtig

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

Reaktionskomponenten müssen in einem einzelnen Behälter verpackt sein, bei dem es sich um ein beliebiges Tag handeln kann, z. "<div> .. </ div>"

Sie können die Rendermethode von ReactCSSTransitionGroup überprüfen

2
Shivprasad P

Mit React 16 erhalten Sie Ihre Rückgabe als Array, sodass es von einem Element wie div umschlossen werden sollte.

Falscher Ansatz

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

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

    );
}

Richtiger Ansatz (Alle Elemente in einem Div oder einem anderen Element, das Sie verwenden)

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

ngültig:Nicht nur untergeordnete Elemente

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>
        )
    }

Valid:Root-Element unter Child-Elementen

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

Ansicht importieren und in View einbinden. Das Einwickeln eines div hat bei mir nicht funktioniert.

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

Für Rect-Native-Entwickler. Beim Rendern von Item in FlatList ist dieser Fehler aufgetreten. Ich hatte zwei Textkomponenten. Ich habe sie wie unten beschrieben benutzt

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

Aber nachdem ich diese zwei Inside View-Komponenten eingesetzt habe, hat es bei mir funktioniert.

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

Möglicherweise verwenden Sie andere Komponenten, aber das Einfügen in View kann für Sie hilfreich sein.

0
GSK