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?
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>
)
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 />
}
},
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
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"),
);
}
Abhängig davon, welche Version von React Sie ausführen, haben Sie einige Optionen, um dies zu beheben:
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.
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>);
}
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.
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 />
</>)
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 />
) ];
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>
);
}
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>
);
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
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>
);
}
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>
)
}
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>
);
}
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.