HelloWorld
-Komponente haben wir schon beim Sprung ins kalte Wasser implementiert. Jedoch war dies natürlich bewusst eine sehr simple Komponente, die nicht gerade sehr praxisnah war und auch längst nicht alles beinhaltet hat was uns React bietet. Aber sie diente als gute erste Veranschaulichung, um die grundsätzliche Funktionsweise von von React und React-Komponenten kennenzulernen.render()
-Funktion was auf dem Bildschirm erscheint.return
-Wert ein explizites null
(undefined
ist dagegen nicht gültig!) oder ein gültiges React.Element
(hier in Form von JSX) und sie empfängt ein props
-Objekt als erstes Funktionsargument, wobei sogar dieses optional ist und ebenfalls null
sein kann.React.Component
oder React.PureComponent
(dazu später mehr) Klasse ableitet und haben mindestens eine Methode mit dem Namen render()
:render()
-Methode einer Klassen-Komponente selbst keinerlei Argumente übergeben, sondern es kann einzig über die Instanz-Eigenschaft this.props
auf die Props zugegriffen werden!displayName
, also der Name einer gültigen Komponente, stets mit einem Großbuchstaben anfängt. Der Rest des Namens kann aus Großbuchstaben oder Kleinbuchstaben bestehen, wichtig ist lediglich, dass der erste Buchstabe stets ein Großbuchstabe ist!section
würde React also als DOM-Element interpretieren, während eine eigene Komponente durchaus den Namen Section
haben kann und wegen ihres Großbuchstabens am Anfang von React korrekt vom section
DOM-Element unterschieden werden würde.React.PureComponent
und funktioniert vom Grundsatz her wie die gewöhnliche Klassen-Komponente, die von React.Component
abgeleitet wird. Mit dem Unterschied, dass React diese Art der Komponente nur dann neu rendert, wenn sich ihre Props oder ihr State im Vergleich zur vorherigen Render-Phase geändert haben. Sie kann zur Optimierung der Performance verwendet werden.logFunction
außerhalb der Klasse. Die fiktive MyComponent
-Komponente bekommt als logger
-Prop hier die Referenz zur logFunction
übergeben. Die Identität der Referenz bleibt hier bei jedem erneuten Rendering bestehen und eine Pure Component würde nicht erneut gerendert, sofern sich ihr eigener State nicht geändert hat, da die Props hier in der Rendering-Phase mit denen aus dem vorherigen Rendering exakt übereinstimmen, also identisch sind.MyComponent
, allerdings erzeugen wir für den Interpreter bei jedem neuen Rendering auch eine neue Funktionsidentität. Dadurch geht der Bezug zur alten Funktion verloren und die Shallow-Comparison, also der oberflächliche Vergleich zwischen den vorherigen und den neuen Props schlägt fehl, ist also unterschiedlich und löst damit ein Rerendering aus.logConfig
-Objekt bzw. das logEntries
-Array bei jedem erneuten Rendering an Ort und Stelle neu erzeugt werden würde.Component
oder PureComponent
ab und wir bestimmen durch die Auswahl der Klasse, von der wir ableiten, ob die Komponente mit jeder Änderung einer sich in der Hierarchie höher befindlichen Komponente neu gerendert werden soll. Diese Möglichkeit haben wir bei Function Components, die lediglich einfache JavaScript-Funktionen sind, nicht. Seit React 16.6.0 bietet React jedoch durch die neue Wrapper-Funktion React.memo()
auch in Function Components die Möglichkeit der Rerendering-Optimierung. Dazu wird diese einfach um die entsprechende Funktion gelegt:React.PureComponent
Klasse abgeleitet wird.App
-Komponente alle 0,2 Sekunden automatisch ein Rerendering aus, ohne dass dabei jedoch Props an ihre Kind-Komponenten übergeben werden. Preisfrage: Welche beiden Komponenten werden dabei jeweils mit neu gerendert und welche beiden nicht?require()
oder import
.<MyApp>
gibt hier ein <div>
zurück, das zweimal die Hello
-Komponente aus dem vorherigen Beispiel benutzt, um Manuel und Tom zu begrüßen. Das Resultat:undefined
!Fragment
-Kurzform benutzt werden, die aus einem leeren öffnenden und schließenden Element besteht:this.props
innerhalb der Klassen-Instanz verfügbar sind, statt über ein Funktionsargument, wie das bei funktionalen Komponenten der Fall ist. Darum kümmert sich React beim Parsing der createElement()
-Aufrufe.shouldComponentUpdate()
Lifecycle-Methode explizit unterbunden werden, doch dazu gibt es im nachfolgenden Kapitel über State und Lifecycle-Methoden mehr. Wichtig ist erst einmal der allgemeine Grundsatz: empfängt eine Komponente von außen neue Props, veranlasst dies React dazu eine Komponente mitsamt ihrer Kind-Komponenten neu zu rendern.5
als Wert, erhalte ich eine 10
zurück. Immer und ausnahmslos. Same input, same output.10
als Argument auf, erhalte ich 1930
zurück (10 + 1920
). Verkleinere ich nun das Fenster auf 1280 Pixel und rufe die Funktion erneut, mit exakt der gleichen 10
als Argument auf bekomme ich dennoch ein anderes Ergebnis (1290
) als beim ersten Mal. Es handelt sich also nicht um eine Pure Function.pureCalculation(10, window.outerWidth)
zwar immer noch ein Ergebnis, das von meiner Fensterbreite abhängt; die Funktion ist dennoch „pure“ da sie bei gleichem Input weiterhin den gleichen Output liefert. Einfacher kann man das nachvollziehen, wenn man die Funktion mal auf ihre wesentlichen Eigenschaften reduziert:props
-Argument einer Function Component, über den constructor()
in einer Klassen-Komponente oder an beliebiger anderer Stelle innerhalb einer Klassen-Komponente mittels this.props
: ich kann und darf (und soll! und will!!) den Wert der hereingereichten Props nicht ändern.number
und fullName
Props innerhalb meiner Example
-Komponente zu ändern, was natürlich nicht funktionieren kann, da wir ja gelernt haben, dass Props grundsätzlich readonly sind.getDerivedStateFromProps()
, auf die ich im nächsten Kapital nochmal gesondert und sehr detailliert eingehen werde.props
, nicht jedoch das props
-Objekt selbst. Das ist überhaupt kein Problem.renderCounter
auf den Anfangswert 0
. Diese Variable zählt für uns gleich mit, wie oft wir unsere App
-Komponente rendern oder genauer gesagt, wie oft wir im Endeffekt die ReactDOM.render()
Funktion aufrufen, die dann entsprechend bei jedem Aufruf dafür sorgt, dass die App
-Komponente erneut gerendert wird.renderCounter
Variable um 1 hoch. Was hier jetzt passiert, ist ganz spannend: Wir modifizieren die renderCounter
Prop unserer App „von außen“.createElement()
sind) kann das nahezu alles sein, solange es eben ein valider Ausdruck ist.