React
JSX
Suche…
Bemerkungen
JSX ist ein Präprozessor-Schritt , der JavaScript um XML-Syntax erweitert. Sie können React definitiv ohne JSX verwenden, aber JSX macht React viel eleganter.
Wie XML haben JSX-Tags einen Tagnamen, Attribute und Kinder. Wenn ein Attributwert in Anführungszeichen eingeschlossen ist, ist der Wert eine Zeichenfolge. Umschließen Sie den Wert andernfalls in geschweifte Klammern, und der Wert ist der eingeschlossene JavaScript-Ausdruck.
Grundsätzlich liefert JSX nur syntaktischen Zucker für die Funktion React.createElement(component, props, ...children)
.
Also der folgende JSX-Code:
class HelloMessage extends React.Component {
render() {
return <div>Hello {this.props.name}</div>;
}
}
ReactDOM.render(<HelloMessage name="Kalo" />, mountNode);
Kompiliert sich mit dem folgenden JavaScript-Code:
class HelloMessage extends React.Component {
render() {
return React.createElement(
"div",
null,
"Hello ",
this.props.name
);
}
}
ReactDOM.render(React.createElement(HelloMessage, { name: "Kalo" }), mountNode);
Beachten Sie abschließend, dass die folgende Zeile in JSX weder eine Zeichenfolge noch HTML ist :
const element = <h1>Hello, world!</h1>;
Es heißt JSX und ist eine Syntaxerweiterung für JavaScript . JSX erinnert Sie möglicherweise an eine Vorlagensprache, verfügt jedoch über die volle Funktionalität von JavaScript.
Das React-Team sagt in seinen Dokumenten, dass es empfohlen wird, es zu verwenden, um zu beschreiben, wie die Benutzeroberfläche aussehen sollte.
Requisiten in JSX
Es gibt verschiedene Möglichkeiten, Requisiten in JSX anzugeben.
JavaScript-Ausdrücke
Sie können jeden JavaScript-Ausdruck als Requisite übergeben, indem Sie ihn mit {}
. Zum Beispiel in dieser JSX:
<MyComponent count={1 + 2 + 3 + 4} />
In MyComponent
der Wert von props.count
10
, da der Ausdruck 1 + 2 + 3 + 4
ausgewertet wird.
Wenn Anweisungen und for-Schleifen keine Ausdrücke in JavaScript sind, können sie nicht direkt in JSX verwendet werden.
String Literals
Natürlich können Sie auch ein beliebiges string literal
als prop
. Diese beiden JSX-Ausdrücke sind gleichwertig:
<MyComponent message="hello world" />
<MyComponent message={'hello world'} />
Wenn Sie ein Zeichenfolgenliteral übergeben, hat der Wert keinen HTML-Code. Diese beiden JSX-Ausdrücke sind also gleichwertig:
<MyComponent message="<3" />
<MyComponent message={'<3'} />
Dieses Verhalten ist normalerweise nicht relevant. Der Vollständigkeit halber wird es hier nur erwähnt.
Standardwert für Requisiten
Wenn Sie keinen Wert für eine Eigenschaft übergeben, wird der Standardwert " true
. Diese beiden JSX-Ausdrücke sind gleichwertig:
<MyTextBox autocomplete />
<MyTextBox autocomplete={true} />
Allerdings sagt der React Team in ihre docs diesem Ansatz wird nicht empfohlen, weil es mit dem ES6 Objekt Stenografie verwechselt werden kann {foo}
, die für kurz {foo: foo}
anstatt {foo: true}
. Sie sagen, dass dieses Verhalten gerade da ist, so dass es dem Verhalten von HTML entspricht.
Attribute verteilen
Wenn Sie bereits Requisiten als Objekt haben und Sie diese in JSX übergeben möchten, können Sie ...
als Spread-Operator verwenden, um das gesamte Requisitenobjekt zu übergeben. Diese beiden Komponenten sind gleichwertig:
function Case1() {
return <Greeting firstName="Kaloyab" lastName="Kosev" />;
}
function Case2() {
const person = {firstName: 'Kaloyan', lastName: 'Kosev'};
return <Greeting {...person} />;
}
Kinder in JSX
In JSX-Ausdrücken, die sowohl ein öffnendes Tag als auch ein schließendes Tag enthalten, wird der Inhalt zwischen diesen Tags als spezielles prop: props.children
. Es gibt verschiedene Möglichkeiten, Kinder zu übergeben:
String Literals
Sie können eine Zeichenfolge zwischen den öffnenden und schließenden Tags setzen, und props.children
wird nur diese Zeichenfolge sein. Dies ist nützlich für viele der integrierten HTML-Elemente. Zum Beispiel:
<MyComponent>
<h1>Hello world!</h1>
</MyComponent>
Dies ist gültiges JSX, und props.children
in MyComponent wird einfach <h1>Hello world!</h1>
.
Beachten Sie, dass der HTML-Code nicht maskiert ist , sodass Sie JSX im Allgemeinen genauso wie HTML schreiben können.
Bedenken Sie, dass in diesem Fall JSX:
- entfernt Leerzeichen am Anfang und Ende einer Zeile;
- entfernt leere Zeilen;
- neue Zeilen neben Tags werden entfernt;
- Neue Zeilen, die in der Mitte von String-Literalen auftreten, werden zu einem einzigen Raum zusammengefasst.
JSX-Kinder
Sie können mehr JSX-Elemente als untergeordnete Elemente angeben. Dies ist nützlich, um verschachtelte Komponenten anzuzeigen:
<MyContainer>
<MyFirstComponent />
<MySecondComponent />
</MyContainer>
Sie können verschiedene Kindertypen zusammenmischen, sodass Sie String-Literale zusammen mit JSX-Kindern verwenden können . Dies ist eine andere Art und Weise, in der JSX wie HTML ist, so dass dies sowohl gültiges JSX als auch gültiges HTML ist:
<div>
<h2>Here is a list</h2>
<ul>
<li>Item 1</li>
<li>Item 2</li>
</ul>
</div>
Beachten Sie, dass eine React-Komponente nicht mehrere React-Elemente zurückgeben kann. Ein einzelner JSX-Ausdruck kann jedoch mehrere untergeordnete Elemente enthalten . Wenn Sie möchten, dass eine Komponente mehrere Elemente rendert, können Sie sie wie im obigen Beispiel in ein div
.
JavaScript-Ausdrücke
Sie können jeden JavaScript-Ausdruck als untergeordnete Elemente übergeben, indem Sie ihn in {}
einschließen. Zum Beispiel sind diese Ausdrücke gleichwertig:
<MyComponent>foo</MyComponent>
<MyComponent>{'foo'}</MyComponent>
Dies ist oft nützlich, um eine Liste von JSX-Ausdrücken mit beliebiger Länge zu rendern. So wird beispielsweise eine HTML-Liste dargestellt:
const Item = ({ message }) => (
<li>{ message }</li>
);
const TodoList = () => {
const todos = ['finish doc', 'submit review', 'wait stackoverflow review'];
return (
<ul>
{ todos.map(message => (<Item key={message} message={message} />)) }
</ul>
);
};
Beachten Sie, dass JavaScript-Ausdrücke mit anderen Kindertypen gemischt werden können.
Funktionen als Kinder
Normalerweise werden in JSX eingefügte JavaScript-Ausdrücke zu einem String, einem React-Element oder einer Liste dieser Elemente ausgewertet. props.children
funktioniert jedoch genauso wie alle anderen Requisiten, da sie jede Art von Daten übergeben können, nicht nur die, die React rendern kann. Wenn Sie beispielsweise eine benutzerdefinierte Komponente haben, können Sie einen Rückruf als props.children
:
const ListOfTenThings = () => (
<Repeat numTimes={10}>
{(index) => <div key={index}>This is item {index} in the list</div>}
</Repeat>
);
// Calls the children callback numTimes to produce a repeated component
const Repeat = ({ numTimes, children }) => {
let items = [];
for (let i = 0; i < numTimes; i++) {
items.push(children(i));
}
return <div>{items}</div>;
};
Untergeordnete Elemente, die an eine benutzerdefinierte Komponente übergeben werden, können alles sein, solange sie von der Komponente in etwas umgewandelt werden, das React vor dem Rendern verstehen kann. Diese Verwendung ist nicht üblich, sie funktioniert jedoch, wenn Sie die Möglichkeiten von JSX erweitern möchten.
Ignorierte Werte
Beachten Sie, dass false
, null
, undefined
und true
gültige Kinder sind. Aber sie rendern einfach nicht. Diese JSX-Ausdrücke werden alle auf dieselbe Weise gerendert:
<MyComponent />
<MyComponent></MyComponent>
<MyComponent>{false}</MyComponent>
<MyComponent>{null}</MyComponent>
<MyComponent>{true}</MyComponent>
Dies ist äußerst nützlich, um React-Elemente bedingt zu rendern. Dieser JSX gibt nur ein aus, wenn showHeader
wahr ist:
<div>
{showHeader && <Header />}
<Content />
</div>
Ein wichtiger Nachteil ist, dass einige "falsche" Werte wie die 0
Zahl immer noch von React gerendert werden. Dieser Code verhält sich beispielsweise nicht wie erwartet, da 0
gedruckt wird, wenn props.messages
ein leeres Array ist:
<div>
{props.messages.length &&
<MessageList messages={props.messages} />
}
</div>
Um dies zu beheben, stellen Sie sicher, dass der Ausdruck vor dem &&
immer boolean ist:
<div>
{props.messages.length > 0 &&
<MessageList messages={props.messages} />
}
</div>
Beachten Sie schließlich, dass Sie einen Wert wie false
, true
, null
oder undefined
in der Ausgabe anzeigen möchten, wenn Sie ihn in einen String konvertieren müssen:
<div>
My JavaScript variable is {String(myVariable)}.
</div>