Was ist der Unterschied zwischen Reaktionskomponente und Reaktionselement? Die Dokumentation erwähnt beide, geht aber nicht ins Detail. Einige Methoden erfordern Komponenten, andere Elemente ...
quelle
Was ist der Unterschied zwischen Reaktionskomponente und Reaktionselement? Die Dokumentation erwähnt beide, geht aber nicht ins Detail. Einige Methoden erfordern Komponenten, andere Elemente ...
Hier gibt es drei verwandte Arten von Dingen mit ihren eigenen Namen:
Dies ist etwas überraschend, da Sie, wenn Sie an andere UI-Frameworks gewöhnt sind, erwarten könnten, dass es nur zwei Arten von Dingen gibt, die ungefähr Klassen (wie Widget
) und Instanzen (wie new Widget()
) entsprechen. Dies ist in React nicht der Fall. Komponenteninstanzen sind nicht dasselbe wie Elemente, und es besteht auch keine Eins-zu-Eins-Beziehung zwischen ihnen. Betrachten Sie zur Veranschaulichung diesen Code:
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
class MyComponent extends React.Component {
constructor(props) {
super(props);
console.log('This is a component instance:', this);
}
render() {
const another_element = <div>Hello, World!</div>;
console.log('This is also an element:', another_element);
return another_element;
}
}
console.log('This is a component:', MyComponent)
const element = <MyComponent/>;
console.log('This is an element:', element);
ReactDOM.render(
element,
document.getElementById('root')
);
Im obigen Code:
MyComponent
(die Klasse selbst ) ist eine Komponenteelement
ist ein Element. Es ist keine Instanz von MyComponent
; Vielmehr handelt es sich lediglich um eine Beschreibung der zu erstellenden Komponenteninstanz. Es ist ein Objekt mit key
, props
, ref
und type
Eigenschaften. Hier key
und ref
sind null
, props
ist ein leeres Objekt, und type
ist MyComponent
.MyComponent
wird beim element
Rendern erstellt (und protokolliert sich im obigen Beispiel von ihrem Konstruktor) .another_element
ist auch ein Element, und hat key
, ref
, props
und type
Eigenschaften wie element
tut - aber diesmal von dem Wert type
ist die Zeichenfolge "div"
.Die Designgründe, warum React diese drei unterschiedlichen Konzepte hat, werden im Blog-Beitrag React Components, Elements and Instances des React-Teams , den ich zum Lesen empfehle, ausführlich untersucht .
Schließlich ist anzumerken, dass in den offiziellen Dokumenten der Begriff "Komponente" für eine Funktion oder Klasse und "Komponenteninstanz" für eine Instanz streng verwendet wird, andere Quellen diese Terminologie jedoch nicht unbedingt einhalten. Sie sollten erwarten, dass "Komponente" (falsch) als "Komponenteninstanz" verwendet wird, wenn Sie Antworten oder Diskussionen zum Stapelüberlauf auf GitHub lesen.
<Child/>
von ihrerrender()
Methode zurückkehrt, wird jedes Mal, wenn sierender()
aufgerufen wird, ein neues Element zurückgegeben, aber eine bereits vorhandeneChild
Komponente kann wiederverwendet werden, um dies zu realisieren Element.)el = <SomeComponent>
und dieses eine Element dann mehrmals in einen großen JSX-Ausdruck einbetten, der von einerrender()
Methode zurückgegeben wird (d. H. Do<div>{el}{el}{el}{el}</div>
).Um die Antwort weiter zu erläutern, verfügt ein Reaktionselement über keine Methoden und nichts über den Prototyp. Das macht sie auch schnell.
"Ein ReactElement ist eine leichte, zustandslose, unveränderliche, virtuelle Darstellung eines DOM-Elements" - Glossar der Reaktionsbegriffe
Eine Reaktionskomponentenfunktion
render()
gibt einen DOM-Baum von Reaktionselementen hinter den Kulissen zurück (dies ist übrigens das virtuelle DOM). Es gibt einige komplexe Mapping- und Diff-Logik, aber im Grunde sind diese React-Elemente den DOM-Elementen zugeordnet.Sie können ein Element auch direkt erstellen,
React.createElement(arg)
wobei arg ein HTML-Tag-Name oder eine React Component-Klasse sein kann.quelle
ReactElement
der VDOM selbst ist ... aber ich bin kein großer Experte in diesem Thema, das ist nur eine Vermutung. Nach meinem Verständnis muss noch eine ReaktionElement
auf ein VDOM gerendert werden, die sich dann vom "vorherigen" VDOM unterscheidet. Ich denkeuser6445533
, die Antwort sagt dasselbe. Recht ? Ich bin kein Experte, aber irgendwie sagt mir der gesunde Menschenverstand, dass dies nach einigem Nachdenken die einzig sinnvolle Interpretation ist ... aber meine Intuition könnte falsch sein.Elemente reagieren
Ein React-Element ist nur ein einfaches altes JavaScript
Object
ohne eigene Methoden. Es hat im Wesentlichen vier Eigenschaften:type
, eineString
Darstellung eines HTML-Tags oder einer Referenz, die sich auf eine Reaktionskomponente beziehtkey
, aString
, um ein Reaktionselement eindeutig zu identifizierenref
, eine Referenz für den Zugriff auf den zugrunde liegenden DOM-Knoten oder die React Component Instance)props
(EigenschaftenObject
)Ein Reaktionselement ist keine Instanz einer Reaktionskomponente. Es ist nur eine vereinfachte "Beschreibung", wie die
type
zu erstellende React Component-Instanz (oder abhängig von einem HTML-Tag) aussehen soll.Ein Reaktionselement, das eine Reaktionskomponente beschreibt, weiß nicht, auf welchen DOM-Knoten sie schließlich gerendert wird. Diese Zuordnung wird abstrahiert und beim Rendern aufgelöst.
Reaktionselemente können untergeordnete Elemente enthalten und können daher Elementbäume bilden, die den virtuellen DOM-Baum darstellen.
Komponenten reagieren und Komponenteninstanzen reagieren
Eine benutzerdefinierte Reaktionskomponente wird entweder durch
React.createClass
oder durch ErweiternReact.Component
(ES2015) erstellt. Wenn eine Reaktionskomponente instanziiert wird, erwartet sie eineprops
Object
und gibt eine Instanz zurück, die als Reaktionskomponenteninstanz bezeichnet wird.Eine React-Komponente kann den Status enthalten und hat Zugriff auf die React Lifecycle-Methoden. Es muss mindestens eine
render
Methode haben, die beim Aufrufen ein Reaktionselement (-tree) zurückgibt. Bitte beachten Sie, dass Sie React Component Instances niemals selbst erstellen, sondern von React für Sie erstellen lassen.quelle
Reaktionselemente vs Reaktionskomponenten
Elemente reagieren
type
Eigenschaften als native HTML-Elemente haben._Es ist wichtig, diese Unterscheidung hier zu treffen, da das Element nicht das ist, was wir auf dem Bildschirm sehen, sondern die Objektdarstellung das ist, was gerendert wird.
Damit kann man gut reagieren:
createElement
Methode können wir eine Objektdarstellung eines DOM-Knotens (auch bekannt als React-Element) erstellen .
Hier werdenconst element = React.createElement( 'div', {id: 'login-btn'}, 'Login' )
createElement
drei Argumente angeführtLogin
)createElement
Aufruf gibt ein Objekt zurück
Wenn dies in das DOM gerendert wird (mit{ type: 'div', props: { children: 'Login', id: 'login-btn' } }
ReactDOM.render
), haben wir einen neuen DOM-Knoten, der so aussieht:<div id='login-btn'>Login</div>
Huzzah!
Komponenten reagieren
Eine Reaktionskomponente ist eine Vorlage. Eine Blaupause. Eine globale Definition. Dies kann entweder eine Funktion oder eine Klasse sein (mit einer Renderfunktion).
Wenn reag eine Klasse oder eine Funktion als erstes Argument sieht, prüft es, welches Element es angesichts der entsprechenden Requisiten rendert, und setzt dies fort, bis keine
createElement
Aufrufe mehr vorhanden sind, deren erstes Argument eine Klasse oder eine Funktion ist .Wenn React ein Element mit einem Funktions- oder Klassentyp sieht, konsultiert es diese Komponente, um zu erfahren, welches Element es angesichts der entsprechenden Requisiten zurückgeben soll.
Am Ende dieses Prozesses verfügt React über eine vollständige Objektdarstellung des DOM-Baums. Dieser gesamte Prozess wird in React als Versöhnung bezeichnet und jedes Mal ausgelöst
setState
oderReactDOM.render
aufgerufen.Erstellen Sie eine Klassenkomponente
// MyComponent.js import React, { Component } from 'react'; class MyComponent extends Component { render() { return ( <div>This is my component.</div> ); } } export default MyComponent;
Verwenden Sie es in jeder anderen Komponente
// MyOtherComponent.js import React, { Component } from 'react'; import MyComponent from './MyComponent'; class MyOtherComponent extends Component { render() { return ( <div> <div>This is my other component.</div> <MyComponent /> </div> ); } } export default MyOtherComponent;
Verwenden Sie Requisiten
<MyComponent myProp="This is passed as a prop." />
Auf Requisiten kann mit zugegriffen werden
this.props
class MyComponent extends Component { render() { const {myProp} = this.props; return ( <div>{myProp}</div> ); } }
Status verwenden
class MyComponent extends Component { render() { const {myState} = this.state || {}; const message = `The current state is ${myState}.`; return ( <div>{message}</div> ); } }
Verwenden von Lifecycle-Hooks
Funktionsbasierte Komponentenclass MyComponent extends Component { // Executes after the component is rendered for the first time componentDidMount() { this.setState({myState: 'Florida'}); } render() { const {myState} = this.state || {}; const message = `The current state is ${myState}.`; return ( <div>{message}</div> ); } }
Mit
createElement
function Button ({ addFriend }) { return React.createElement( "button", { onClick: addFriend }, "Add Friend" ) } function User({ name, addFriend }) { return React.createElement( "div", null, React.createElement( "p", null, name ), React.createElement(Button, { addFriend }) ) }
Mit was
createElement
kehrt zurückfunction Button ({ addFriend }) { return { type: 'button', props: { onClick: addFriend, children: 'Add Friend' } } } function User ({ name, addFriend }) { return { type: 'div', props: { children: [ { type: 'p', props: { children: name } }, { type: Button, props: { addFriend } } ] } } }
Hier haben wir eine
Button
Komponente, die eineonLogin
Eingabe akzeptiert und ein React-Element zurückgibt.Button
Komponente erhält eineonLogin
Methode als Eigenschaft.id
Attribut getan haben.quelle
React Element
- Es ist ein einfaches Objekt, das einen DOM-Knoten und seine Attribute oder Eigenschaften beschreibt, die Sie sagen können. Es ist ein unveränderliches Beschreibungsobjekt, auf das Sie keine Methoden anwenden können.Z.B -
<button class="blue"></button>
React Component
- Es ist eine Funktion oder Klasse, die eine Eingabe akzeptiert und ein React-Element zurückgibt. Es muss Verweise auf seine DOM-Knoten und auf die Instanzen der untergeordneten Komponenten beibehalten.const SignIn = () => ( <div> <p>Sign In</p> <button>Continue</button> <button color='blue'>Cancel</button> </div> );
quelle
Eine Komponente ist eine Fabrik zum Erstellen von Elementen.
quelle
Ein Element ist ein einfaches Objekt, das beschreibt, was auf dem Bildschirm in Bezug auf die DOM-Knoten oder andere Komponenten angezeigt werden soll. Elemente können andere Elemente in ihren Requisiten enthalten. Das Erstellen eines React-Elements ist billig. Sobald ein Element erstellt wurde, wird es nie mehr mutiert. Die Objektdarstellung des React-Elements wäre wie folgt:
const element = React.createElement( 'div', {id: 'login-btn'}, 'Login' )
Das obige createElement gibt als Objekt wie folgt zurück:
{ type: 'div', props: { children: 'Login', id: 'login-btn' } }
Und schließlich wird es mit ReactDOM.render wie folgt in das DOM gerendert.
<div id='login-btn'>Login</div>
Während eine Komponente auf verschiedene Arten deklariert werden kann. Es kann eine Klasse mit einer render () -Methode sein. Alternativ kann es in einfachen Fällen als Funktion definiert werden. In beiden Fällen werden Requisiten als Eingabe verwendet und ein Elementbaum als Ausgabe zurückgegeben. JSX wurde am Ende als createElement transpiliert.
function Button ({ onLogin }) { return React.createElement( 'div', {id: 'login-btn', onClick: onLogin}, 'Login' ) }
quelle
Hier ist meine Einstellung:
Element
beschreibt, wie das VDOM erstellt wird. Es ist im Grunde eine "eingefrorene" Version des entsprechendenComponent Instance
.Wenn alles wäre,
functional component
wäre keine zusätzliche Reaktion erforderlichElement
. Diefunctional component
Hierarchie könnte den VDOM-Baum direkt erzeugen.Eine Reaktionshierarchie
Component Instance
(tree
) ist eine "Fabrik", und diese Fabrik wird durch die Requisiten parametrisiert, die der Wurzelreaktion zugeführt werden,Component Instance
und durch den gesamten Zustand, der irgendwo imComponent Instance
Baum "gespeichert" ist .Die Reaktion
Element
ist also im Grunde ein "abstrakter Syntaxbaum", der in das eigentliche VDOM kompiliert wird.Warum also nicht das VDOM direkt mit der Reaktion generieren
Component Instances
? Das ist hier die eigentliche Frage.Auf den ersten Blick verstehe ich nicht, warum das nicht möglich wäre. Die Antwort lautet also höchstwahrscheinlich, dass es sich um eine Frage der Leistung handelt.
Die Reaktion
Element
ist eine Abstraktionsebene zwischen dem VDOM und demComponent Instance
, warum diese Abstraktion benötigt wird, ist mir nicht ganz klar, höchstwahrscheinlich erlaubt sie Optimierungen. Beispielsweise wird derElement
Baum nicht vollständig gerendert, wenn eine Lebenszyklusmethode auf demComponent Instance
besagt, dass dieser Teilbaum nicht gerendert werden muss.In diesem Fall "benötigt" die Logik, die diese Optimierung handhabt, diese zusätzliche Indirektionsebene - da die Informationen an einem Ort gespeichert werden müssen, an dem ein Teil des VDOM nicht mit dem neuen VDOM verglichen werden sollte, noch mehr, vielleicht der neue VDOM sollte überhaupt nicht berechnet werden. Die Verwendung einer zusätzlichen Indirektionsebene vereinfacht die Renderlogik und führt zu einer saubereren und wartbareren Implementierung - wie ich mir vorstellen kann.
Dieses Konzept in Haskell heißt " Heben ":
Zum Beispiel sind Monaden in Haskell perfekte Beispiele für solche Aufzüge.
Eine Monade ist eine Art Beschreibung einer Berechnung, die wie folgt als Wert gespeichert werden kann
42
. In ähnlicher Weise reagierenElements
Elemente einer Beschreibung, wie das "neue" VDOM berechnet wird. Wenn jemand es berechnen will.Dieser Vortrag beschreibt dieses Konzept einer "zusätzlichen" Indirektion mit einigen einfachen Beispielen :
Mit anderen Worten: Vorzeitige Optimierung ist die Wurzel allen Übels.
Oder: Grundsatz der Softwareentwicklung
Nach meinem Verständnis sind Reagieren
Elements
ein Implementierungsdetail, um die Komplexität angemessen zu handhaben und eine gewisse Optimierung (Leistung) zu ermöglichen. Ich verstehe nicht, warum man diese zusätzliche Indirektion nicht loswerden konnte - im Prinzip - reagieren würde immer noch "genauso gut" funktionieren - aber es könnte sehr langsam sein, die Implementierung und Wartung der reaktionsfähigen "Engine" selbst wäre wahrscheinlich ein Albtraum .Bitte korrigieren Sie mich, wenn mir hier etwas fehlt.
Zitieren eines WICHTIGEN Teils der Antwort von user6445533:
DAS IST DER SCHLÜSSEL ^^^^
Element IST NICHT VDOM.
quelle
A
React Element
ist das, was Sie als grundlegendes HTML-Element (genauer gesagt dom) betrachten würden. Es ist nur eine Möglichkeit, Elemente zu erstellen, ohne das umstrittene jsx-Format zu verwenden.A
React Component
ist das, was Sie als Objekt betrachten können. Es hat seine Methoden, unterstütztReact lifecycles
und ist im Allgemeinen nicht wiederverwendbar (zumindest noch keine Wiederverwendung gefunden, willkommen zu Beispielen). Es muss unbedingt eine Renderfunktion haben.A
React Class
nennt man eine Klasse. Funktionalität weiseReact Class
undReact Component
sind gleich. Nur die Syntax ist die eigentliche Änderung, auf derReact Component
basiertES6 syntax
. Eine weitere wichtige Änderung ist, dass die Standardbindung von Funktionen an diese nicht mehr unterstützt wird, es sei denn, Sie verwenden Pfeilfunktionen.Mixins
werden ab sofort auch nicht mehr unterstütztES6
.quelle
Elemente sind Thunks.
Mit React können Sie Benutzeroberflächen als reine Funktionen definieren, die im Anwendungsstatus definiert sind. Dies könnte implementiert werden, indem die gesamte Benutzeroberfläche bei jeder Statusänderung berechnet wird. Dies wäre jedoch teuer. Elemente sind rechnerische Beschreibungen (Thunks). Wenn sie sich nicht ändern und Sie
PureComponent
s verwenden, wird React diesen Teilbaum nicht neu berechnen.quelle
Reaktionskomponenten sind veränderlich, Elemente dagegen nicht
quelle