React ist ein verdammt gutes Framework, das von einer Gruppe verdammt guter Coder bei Facebook gebaut wurde. Es implementiert ein virtuelles DOM und verwendet einen DOM-ähnlichen Ansatz, um sofort die Komponenten hinzuzufügen, die du brauchst, und diejenigen sofort zu entfernen, die du nicht brauchst. React spielt die Rolle des V in der MVC-Struktur, aber wenn du es mit Flux kombinierst, hast du ein verdammt gutes Framework, das M und V mühelos synchronisiert. Mehr zu Flux später~

Komponenten
In React kannst du eine Komponente mit spezieller Funktionalität erstellen, die du in HTML-Elementen nicht finden würdest, selbst wenn du mit einer Laterne danach suchen würdest, wie zum Beispiel die Dropdown-Navigation in diesem Tutorial. Jede Komponente hat ihr eigenes Territorium (Scope), also können wir eine Komponente, sobald wir sie definiert haben, immer wieder wiederverwenden, ohne mit anderen Komponenten interagieren zu müssen!
Jede Komponente hat eine Funktion namens render, die das HTML effizient zurückgibt, das in den Browser geschossen werden soll. Wir können auch andere React-Komponenten aufrufen, was bedeutet: Sobald du in React einsteigst, ist es so tief wie das Meer – oh nein, es ist „Nichts ist unmöglich, nur unvorstellbar.“
JSX
Wenn du React genau beachtest, fällt dir vielleicht etwas namens JSX auf. JSX ermöglicht es uns, HTML in JavaScript zu schreiben, statt HTML zu verwenden, um JavaScript zu enthalten. Es hilft uns, schnell zu entwickeln, weil wir uns keine Gedanken über Strings, Zeilenumbrüche und Ähnliches machen müssen. Du kannst JSX im Browser ausführen, aber das ist nicht empfehlenswert, weil es deine Seite verlangsamt. Gulp und Grunt bieten einen JSX-Interpreter für deine Vorverarbeitungsaufgaben, wenn du JSX verwenden möchtest, empfehle ich, diese Funktion zu aktivieren.
JSX verwenden
Wie bereits erwähnt, hat in JSX jede Komponente eine render-Methode, die ein „ViewModel“ erzeugt – bevor du HTML an die Komponente zurückgibst, kannst du die Informationen aus diesem ViewModel in die View einfügen, was bedeutet, dass sich dein HTML dynamisch basierend auf diesem Modell ändert (zum Beispiel eine dynamische Liste).
Wenn du fertig bist, kannst du zurückgeben, was auch immer du rendern möchtest. JSX dafür zu verwenden, ist so einfach.
var ExampleComponent = React.createClass({
render: function () {
return (
<div className="navigation">
Hello World!
</div>
);
}
});
Wenn du diesen Code in deinem Browser ausgeführt hättest, würdest du nur einen Syntaxfehler erhalten, denn in JavaScript müssen die Zeichen < und > in Anführungszeichen gesetzt werden. Wenn du den JSX-Interpreter auf den Code anwendest, wird er in Folgendes umgewandelt.
var ExampleComponent = React.createClass({
render: function () {
return (
React.createElement('div', {className: 'navigation'}, 'Hello World!')
);
}
});
Du kannst hier klicken, um das Beispiel zu testen.- Ich verwende den Browser-JSX-Interpreter (nicht empfohlen, aber für JSFiddle).
Es hat funktioniert! JSX interpretiert das, was du mit React.createElement erzeugt hast:alleDOM-Knoten, wobei Knotentypen, Parameter und Inhalt generiert werden. Du kannst auf JSX verzichten, aber dann musst du alle DOM-Knoten manuell über React.createElement schreiben. Unzählige Beispiele sagen mir, dass ich JSX verwenden soll.
Du fragst dich sicher, warum ich className statt class im DOM verwende. Das liegt daran, dass class ein reserviertes Wort in JavaScript ist. Wenn JSXdeinen Code interpretiert, wandelt es alle Attribute auf dem Knoten in ein Objekt um, aber du kannst das Objekt nicht als Attribut behandeln!
Variablen in Props verwenden
Wenn du die Style-Klasse einer Komponente (oder einen anderen Attributwert) dynamisch ändern möchtest, kannst du Variablen verwenden. Du kannst jedoch nicht einfach einen Variablennamen übergeben; du musst ihn außerdem in ein Paar geschweifte Klammern setzen, damit JSX weiß, dass es sich um eine externe Variable handelt.
var ExampleComponent = React.createClass({
render: function () {
var navigationClass = 'navigation';
return (
<div className={ navigationClass }>
Hello World!
</div>
);
}
});
Du kannst diese Funktion hier sehen.
Der initiale Renderer
Wenn du zum ersten Mal eine React-Komponente rendern möchtest, musst du React sagen, welche Komponente gerendert werden soll, und außerdem einen vorhandenen DOM-Knoten angeben, um anzugeben, wo diese Komponente gerendert werden soll. Dazu verwendest du die React.render-Funktion.
var ExampleComponent = React.createClass({
render: function () {
return (
<div className="navigation">
Hello World!
</div>
);
}
});
React.render(<ExampleContent />, document.body);
Es rendert die Komponente auf dem body-Knoten – einfach, oder! Von da an kannst du andere Komponenten wie gewohnt aufrufen, oder, wenn du möchtest, die render-Funktion viele Male verwenden, falls du nicht React zum Rendern der gesamten Seite verwenden möchtest, aber trotzdem mehrere Komponenten nutzen willst.
Die Grundlagen einer Komponente
Komponenten können einen eigenen „Zustand“ haben. Dadurch können wir dieselbe Komponente viele Male wiederverwenden und sie dennoch völlig unterschiedlich aussehen lassen, denn der Zustand jeder Komponenteninstanz ist einzigartig.
Wenn du Eigenschaften an eine Komponente übergibst, werden diese props genannt. Beschränke dich nicht auf HTML-Attribute; du kannst alles übergeben, was du möchtest, und innerhalb der Komponente über this.props darauf zugreifen. Dadurch können wir dieselbe Komponente wiederverwenden, aber einen anderen Satz von props übergeben, etwa die „Konfiguration“ der Komponente.
Props
Aufbauend auf unserem früheren „Hello World!“-Beispiel hatten wir das className-Attribut am HTML-Knoten. Innerhalb der Komponente können wir auf diesen Wert mit this.props.classname zugreifen, aber wie bereits erwähnt, kannst du alles übergeben, was du möchtest. Für unser Dropdown müssen wir die Navigation als Objekt konfigurieren, das die Komponente als Konfiguration zum Rendern verwendet. Legen wir los—
var navigationConfig = [];
var Navigation = React.createClass({
render: function () {
return (
<div className="navigation">
</div>
);
}
});
React.render(<Navigation config={ navigationConfig } />, document.body);
Wenn wir jetzt auf this.props.config zugreifen, erhalten wir ein leeres Array (den Wert von navigationConfig). Bevor wir uns mit dem eigentlichen Navigationscode befassen, erklären wir State.
State
Wie bereits erwähnt, hat jede Komponente ihren eigenen „State“. Wenn du State verwendest, definierst du zuerst den initialen State, und erst dann kannst du this.setState verwenden, um ihn zu aktualisieren. Immer wenn der State aktualisiert wird, ruft die Komponente die render-Funktion erneut auf und verwendet die neuen Werte, um das zuvor Gerenderte zu ersetzen oder zu ändern. Das ist die Essenz des virtuellen DOM – der Diffing-Algorithmus findet innerhalb von React statt, sodass wir uns nicht auf DOM-Updates verlassen müssen (weil das DOM langsam ist). React berechnet die Unterschiede und erzeugt eine Reihe von Anweisungen (zum Beispiel das Hinzufügen der Klasse „active“ zu „navigation__link“ oder das Entfernen eines Knotens) und führt sie dann im DOM aus.
Für die Navigation speichern wir den geöffneten Zustand des Dropdown-Menüs im State. Dazu füge dem Klassenkonfigurationsobjekt eine getInitialState-Funktion hinzu und gib ein Objekt mit dem gewünschten initialen State zurück.
var navigationConfig = [];
var Navigation = React.createClass({
getInitialState: function () {
return {
openDropdown: -1
};
},
render: function () {
return (
<div className="navigation">
</div>
);
}
});
React.render(<Navigation config={ navigationConfig } />, document.body);
Du wirst bemerken, dass wir ihn auf -1 gesetzt haben. Wenn wir ein Dropdown öffnen wollen, verwenden wir die Position des Navigationselements im Konfigurations-Array, das im State gespeichert ist, und da Array-Indizes bei 0 beginnen, müssen wir -1 verwenden, um anzugeben, dass derzeit kein Navigationselement angesteuert wird.
Wir können mithilfe von this.state auf den State zugreifen; wenn wir uns also this.state.openDropdown ansehen, sollte -1 zurückgegeben werden.
Komponenten-Lebenszyklus
Jede Komponente hat ihren „Lebenszyklus“ – eine Reihe von Funktionen, die Sie in der Konfiguration der Komponente definieren können und die im Laufe des Lebens der Komponente aufgerufen werden. Wir haben bereits getinitialstate gesehen – es wird nur einmal aufgerufen, wenn die Komponente gemountet wird.
componentWillMount
Diese Funktion wird aufgerufen, wenn die Komponente kurz davor ist, gemountet zu werden. Das bedeutet, dass wir hier Code ausführen können, der für die Funktionsweise der Komponente erforderlich ist. Da render während des Lebenszyklus der Komponente mehrfach aufgerufen wird, platzieren wir hier normalerweise Code, der nur einmal ausgeführt werden muss, z. B. XHR-Anfragen.
var ExampleComponent = React.createClass({
componentWillMount: function () {
// xhr request here to get data
},
render: function () {
// this gets called many times in a components life
return (
<div>
Hello World!
</div>
);
}
});
componentDidMount
Sobald Ihre Komponente die render-Funktion ausgeführt und tatsächlich in das DOM gerendert wurde, wird componentDidMount aufgerufen. Hier können wir alle DOM-Operationen ausführen, die wir benötigen, sowie alles, was davon abhängt, dass die Komponente tatsächlich bereits im DOM existiert, z. B. das Rendern eines Diagramms. Sie können intern über den Aufruf von this.getDOMNode auf den DOM-Knoten zugreifen.
var ExampleComponent = React.createClass({
componentDidMount: function () {
var node = this.getDOMNode();
// render a chart on the DOM node
},
render: function () {
return (
<div>
Hello World!
</div>
);
}
});
componentWillUnmount
Diese Funktion wird aufgerufen, wenn Sie kurz davor sind, die Komponente aus dem DOM zu entfernen. Dadurch können wir hinter der Komponente aufräumen, z. B. alle Event-Listener entfernen, die wir gebunden haben. Wenn wirnichtnach uns aufräumen, dann, wenn eines dieser Events ausgelöst wird, wird versucht, Berechnungen auf einer Komponente durchzuführen, die nicht gemountet wurde, und React wird einen Fehler werfen.
var ExampleComponent = React.createClass({
componentWillUnmount: function () {
// unbind any event listeners specific to this component
},
render: function () {
return (
<div>
Hello World!
</div>
);
}
});
Komponentenmethoden
React stellt außerdem Methoden für Komponenten bereit, um unsere Arbeit zu erleichtern. Sie werden während des Erstellungsprozesses der Komponente aufgerufen. Zum Beispiel können wir mit getInitialState einen Standard-State definieren, sodass wir uns im Code keine weiteren Gedanken darüber machen müssen, ob ein State-Element existiert.
getDefaultProps
Wenn wir eine Komponente erstellen, können wir Standardwerte für die Props der Komponente nach eigenem Ermessen festlegen. Das bedeutet: Wenn wir die Komponente aufrufen und keine Werte für diese Props festlegen, hat die Komponente eine Standard-„Konfiguration“, und wir müssen uns keine Gedanken darüber machen, die Props in der nächsten Codezeile zu prüfen.
Wenn Sie eine Komponente definieren, werden diese Standard-Props zwischengespeichert, sodass sie für jede Instanz der Komponente gleich sind und nicht geändert werden können. Für die Navigationskomponente setzen wir die Konfiguration auf ein leeres Array, sodass selbst dann, wenn keine Konfiguration übergeben wird, in der Render-Methode kein Fehler auftritt.
var Navigation = React.createClass({
getInitialState: function () {
return {
openDropdown: -1
};
},
getDefaultProps: function () {
return {
config: []
}
},
render: function () {
return (
<div className="navigation">
</div>
);
}
});
React.render(<Navigation config={ navigationConfig } />, document.body);
propTypes
Wir können auch für jede Prop nach Wunsch einen Typ angeben. Das ist sehr nützlich, um unerwartete Werte zu prüfen und zu behandeln, die Props zugewiesen werden. Wie im Dropdown unten legen wir fest, dass nur Arrays in die Konfiguration gesetzt werden können.
var Navigation = React.createClass({
getInitialState: function () {
return {
openDropdown: -1
};
},
getDefaultProps: function () {
return {
config: []
}
},
propTypes: {
config: React.PropTypes.array
},
render: function () {
return (
<div className="navigation">
</div>
);
}
});
React.render(<Navigation config={ navigationConfig } />, document.body);
mixins
Wir können Komponenten auch Mixins hinzufügen. Dies ist eine grundlegende Komponente unabhängig von React (nur eine Konfiguration vom Typ Objekt). Das bedeutet: Wenn wir zwei Komponenten mit ähnlicher Funktionalität haben, können wir eine Konfiguration gemeinsam nutzen (wenn der Ausgangszustand derselbe ist). Wir können abstrakt eine Methode im Mixin erstellen, sodass wir denselben Code nicht zweimal schreiben müssen.
var ExampleMixin = {
componentDidMount: function () {
// bind some event listeners here
},
componentWillUnmount: function () {
// unbind those events here!
}
};
var ExampleComponent = React.createClass({
mixins: [ExampleMixin],
render: function () {
return (
<div>
Hello World!
</div>
);
}
});
var AnotherComponent = React.createClass({
mixins: [ExampleMixin],
render: function () {
return (
<div>
Hello World!
</div>
);
}
});
Auf diese Weise haben alle Komponenten dieselben componentDidMount- und componentWillUnmount-Methoden, was uns das Neuschreiben von Code erspart. Jedenfalls können Sie diese Eigenschaften nicht überschreiben; wenn eine Eigenschaft in einem Mixin festgelegt ist, kann sie in dieser Komponente nicht überschrieben werden.
Iterationsschleifen
Wenn wir ein Array mit Objekten haben, wie durchlaufen wir dieses Array und rendern jedes Objekt in Listenelemente? JSX ermöglicht es Ihnen, es in jeder JavaScript-Datei zu verwenden. Sie können mit map über das Array iterieren und JSX zurückgeben und dann React verwenden, um es zu rendern.
var navigationConfig = [
{
href: 'http://ryanclark.me',
text: 'My Website'
}
];
var Navigation = React.createClass({
getInitialState: function () {
return {
openDropdown: -1
};
},
getDefaultProps: function () {
return {
config: []
}
},
propTypes: {
config: React.PropTypes.array
},
render: function () {
var config = this.props.config;
var items = config.map(function (item) {
return (
<li className="navigation__item">
<a className="navigation__link" href={ item.href }>
{ item.text }
</a>
</li>
);
});
return (
<div className="navigation">
{ items }
</div>
);
}
});
React.render(<Navigation config={ navigationConfig } />, document.body);
Sie können navigationConfig gerne in JSFiddle verwenden.
Die Navigationskonfiguration besteht aus einem Array und Objekten, einschließlich eines href-Attributs, das auf einen Hyperlink verweist, und eines text-Attributs für die Anzeige. Wenn wir mappen, durchläuft es das Array Element für Element, um Objekte zu erhalten. Wir können auf href und text zugreifen und sie in HTML verwenden. Beim Zurückgeben der Liste werden die Listenelemente in diesem Array alle ersetzt, sodass React, wenn wir es zur Verarbeitung hineingeben, weiß, wie es gerendert werden muss!
Mixins
Bisher haben wir das Aufklappen aller Dropdown-Listen erreicht. Wir müssen wissen, welches Element gerade aufgeklappt wird. Wir werden die Eigenschaft .children verwenden, um unser navigationConfig-Array zu durchlaufen. Als Nächstes können wir die Unterelemente des Dropdowns durchlaufen.
var navigationConfig = [
{
href: 'http://ryanclark.me',
text: 'My Website',
children: [
{
href: 'http://ryanclark.me/how-angularjs-implements-dirty-checking/',
text: 'Angular Dirty Checking'
},
{
href: 'http://ryanclark.me/getting-started-with-react/',
text: 'React'
}
]
}
];
var Navigation = React.createClass({
getInitialState: function () {
return {
openDropdown: -1
};
},
getDefaultProps: function () {
return {
config: []
}
},
propTypes: {
config: React.PropTypes.array
},
render: function () {
var config = this.props.config;
var items = config.map(function (item) {
var children, dropdown;
if (item.children) {
children = item.children.map(function (child) {
return (
<li className="navigation__dropdown__item">
<a className="navigation__dropdown__link" href={ child.href }>
{ child.text }
</a>
</li>
);
});
dropdown = (
<ul className="navigation__dropdown">
{ children }
</ul>
);
}
return (
<li className="navigation__item">
<a className="navigation__link" href={ item.href }>
{ item.text }
</a>
{ dropdown }
</li>
);
});
return (
<div className="navigation">
{ items }
</div>
);
}
});
React.render(<Navigation config={ navigationConfig } />, document.body);
Beispiel hier- Aber wir können die Dropdown-Elemente immer noch sehen, obwohl wiropenDropdown auf ... gesetzt haben-1 。
Wir können in der Komponente aufthis.statezugreifen, um festzustellen, ob das Dropdown geöffnet ist, und wir können ihr eine neue CSS-Stilklasse hinzufügen, um den Hover-Effekt anzuzeigen.
var navigationConfig = [
{
href: 'http://ryanclark.me',
text: 'My Website',
children: [
{
href: 'http://ryanclark.me/how-angularjs-implements-dirty-checking/',
text: 'Angular Dirty Checking'
},
{
href: 'http://ryanclark.me/getting-started-with-react/',
text: 'React'
}
]
}
];
var Navigation = React.createClass({
getInitialState: function () {
return {
openDropdown: -1
};
},
getDefaultProps: function () {
return {
config: []
}
},
openDropdown: function (id) {
this.setState({
openDropdown: id
});
},
closeDropdown: function () {
this.setState({
openDropdown: -1
});
},
propTypes: {
config: React.PropTypes.array
},
render: function () {
var config = this.props.config;
var items = config.map(function (item, index) {
var children, dropdown;
if (item.children) {
children = item.children.map(function (child) {
return (
<li className="navigation__dropdown__item">
<a className="navigation__dropdown__link" href={ child.href }>
{ child.text }
</a>
</li>
);
});
var dropdownClass = 'navigation__dropdown';
if (this.state.openDropdown === index) {
dropdownClass += ' navigation__dropdown--open';
}
console.log(this.state.openDropdown, index);
dropdown = (
<ul className={ dropdownClass }>
{ children }
</ul>
);
}
return (
<li className="navigation__item" onMouseOut={ this.closeDropdown } onMouseOver={ this.openDropdown.bind(this, index) }>
<a className="navigation__link" href={ item.href }>
{ item.text }
</a>
{ dropdown }
</li>
);
}, this);
return (
<div className="navigation">
{ items }
</div>
);
}
});
React.render(<Navigation config={ navigationConfig } />, document.body);
Siehe das Beispiel hier– Wenn man mit der Maus über "My Website" fährt, erscheint das Dropdown.
Zuvor habe ich jedem Listenelement Maus-Events hinzugefügt. Wie Sie sehen können, habe ich den Aufruf.bind(bind) verwendet, anstatt ihn auf andere Weise aufzurufen – das liegt daran, dass wir, wenn die Maus des Benutzers den Elementbereich verlässt, uns nicht darum kümmern müssen, wo sich der Cursor befindet; wir müssen nur wissen, dass wir das Dropdown schließen, also können wir seinen Wert auf -1 setzen. Wenn die Maus des Benutzers jedoch eintritt, müssen wir wissen, welches Element erweitert wird, also müssen wir diesen Parameter kennen (den Index des Elements). Wir verwenden die Bind-Methode zum Aufrufen, anstatt einfach über eine Funktion aufzurufen, weil wir es über React aufrufen müssen. Wenn wir es direkt aufrufen würden, müssten wir es ständig aufrufen, anstatt es im Event aufzurufen.
Jetzt können wir viele Elemente zunavigationConfig hinzufügen, und wir können auch Stile zum Dropdown-Feature hinzufügen.Beispiel ansehen。
Zusammenfassung
React ist ein einfaches, bequemes, benutzerfreundliches und leistungsstarkes Framework. Seine prägnante API ermöglicht es, schnell eigene Komponenten zu erstellen, ohne sich mit komplexem DOM zu befassen oder besonders komplizierte Operationen durchzuführen, insbesondere bei wiederholten Listenelementen und Ähnlichem.
Quelle: http://www.oschina.net/translate/getting-started-with-react