# Rendering von Elementen

In den vorherigen Kapiteln habe ich sie wie selbstverständlich bereits einige Male erwähnt, doch was genau sind **React-Elemente** eigentlich?

**React-Elemente** sind der kleinstmögliche Baustein in einer **React-Anwendung**. Anhand der **Elemente** beschreibt ihr, was der Benutzer später auf dem Bildschirm zu sehen bekommt. Trotz ihres gleichen Namens unterscheiden sie sich von DOM-Elementen in einem wesentlichen Punkt: Sie sind lediglich ein einfaches Objekt und damit auch günstig (im Sinne der Performance) zu erstellen. Die bloße Erstellung eines **React-Elements** mittels `React.createElement()` löst dabei noch keine DOM-Operation aus!

{% hint style="info" %}
React-**Elemente** werden oftmals mit React-**Komponenten** durcheinander geworfen oder im Sprachgebrauch analog verwendet. Das ist aber nicht korrekt! **Elemente** sind das, aus dem **Komponenten** letztendlich bestehen. **Komponenten** werden im nächsten Kapitel noch ausführlich behandelt, bevor es damit weitergeht, solltest du jedoch zuerst dieses Kapitel über **Elemente** gelesen haben.
{% endhint %}

Wir wissen bereits, wie wir mittels **JSX** ein **React-Element** erstellen und dass **JSX** nur eine Vereinfachung ist, um uns viel Schreibarbeit und ständige `React.createElement()`-Aufrufe zu ersparen. Doch wie rendern wir ein erstelltes Element nun, also mit anderen Worten, zeigen es im Browser an?

Hier bedienen wir uns an `ReactDOM`, genauer gesagt dessen eigener `render()`-Methode. Um ein **React-Element** zu rendern, benötigen wir grundsätzlich eine **Root-** oder **Mount-Node**. Dies ist eine DOM-Node, die sozusagen als Platzhalter dient und React mitteilt, wohin ein Element gerendert werden soll. Theoretisch kannst du problemlos mehrere Root-Nodes in deinem HTML-Dokument haben. React kontrolliert diese alle unabhängig voneinander. Statt also nur einer großen **React-Anwendung** kannst du also auch viele kleine (oder auch große) Anwendungen in einem einzigen HTML-Dokument unterbringen. Üblich ist es aber nur **eine Root-Node** für deine **React-Anwendung** zu haben.

Kommen wir also zum Wesentlichen: um ein **React-Element** zu rendern, übergibst du dieses als erstes Argument der `ReactDOM.render()`-Methode zusammen mit der **Root-Node** als zweitem Argument, also der DOM-Node, in das dein **Element** gerendert werden soll.

Stellen wir uns einmal vor du hast ein `div` mit der ID `root`in deinem HTML-Dokument, das als **Root-Node** dienen soll:

```markup
<!DOCTYPE html>
<html>
  <head>
    <title></title>
  </head>
  <body>
    <div id="root"></div>
  </body>
</html>
```

Der entsprechende Aufruf ist dann der folgende:

```jsx
const myFirstElement = <div>Mein erstes React Element</div>;
ReactDOM.render(myFirstElement, document.getElementById('root'));
```

Führst du diesen Code nun im Browser aus, siehst du **innerhalb** des `root`-divs nun dein `<div>Mein erstes React Element</div>`.

**React-Elemente** sind dabei **immutable**, also unveränderlich. Dies bedeutet: Ist ein Element einmal erstellt, repräsentiert es immer einen bestimmten Zustand („State“) im User Interface. Die offizielle React-Dokumentation spricht hier metaphorisch von einem Einzelbild („Frame“) in einem Film. Möchten wir unser User Interface aktualisieren, müssen wir dazu ein neues **React-Element** mit den veränderten Daten erstellen. Keine Angst, das klingt umständlicher als es ist und passiert später einmal ganz intuitiv.

React selbst ist dabei so klug, dass es durch einen Vergleichsalgorithmus nur die Teile einer Anwendung aktualisiert, die sich auch tatsächlich verändert haben. Dabei werden **React-Elemente** und ihre Kind-Elemente mit ihren Vorgängerversionen verglichen und lösen nur eine DOM-Operation aus, wenn eine Änderung vorliegt. Dies führt dazu, dass React Anwendungen, richtig gemacht, sehr gute Rendering-Performance aufweisen, da DOM-Operationen in der Regel sehr kostspielig (also performancelastig) sind, durch React und seinen **Reconciliation** genannten Prozess aber auf ein Minimum verringert werden. Dabei werden nicht immer grundsätzlich ganze DOM-Elemente anhand der Beschreibung eines **React-Elements** neu erzeugt, sondern es werden auch nur einzelne Attribute aktualisiert, sollte sich nur ein solches geändert haben.

Schauen wir uns das mal in der Praxis an:

```javascript
function showTime() {
  var time = new Date().toLocaleTimeString();
  var timeElement = (
    <div>
      <p>Es ist jetzt {time} Uhr</p>
    </div>
  );
  ReactDOM.render(timeElement, document.getElementById('root'));
}
setInterval(showTime, 1000);
```

Wieder erstellen wir ein **React-Element**, diesmal soll es uns beim Aufruf von `ReactDOM.render()` die aktuelle Zeit ausgeben. Da wir stets die genaue Uhrzeit wissen wollen, stecken wir das Element und den `ReactDOM.render()` Aufruf in eine Funktion, die per `setInterval` alle 1000 ms aufgerufen wird.

Ein Blick in die **Chrome Devtools** offenbart: Bei jedem `ReactDOM.render()`-Aufruf wird stets nur die Uhrzeit selbst aktualisiert, die restlichen Elemente, wie die DOM-Nodes oder auch nicht betroffene Teil des angezeigten Textes bleiben unangetastet:

![React aktualisiert nur die Zeit selbst, nichts anderes.](https://1901581635-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-L9vww5Hf5-h1SCBujws%2F-LfVsUPBBfSMuLTvQnkk%2F-LASsLGI3VxlrTNuD7cL%2Freact-update.png?alt=media\&token=24152722-4fac-4e6e-bafc-c13cd4c05684)

Und hier lernen wir zugleich auch eins der grundlegenden Prinzipien von React in der Praxis kennen: das **deklarative** Vorgehen zur Erstellung von User Interfaces. Statt unserer Mini-App **imperativ** zu sagen, dass sie bitte sekündlich die Uhrzeit aktualisieren soll, definieren wir stattdessen **deklarativ** im **React-Element**, dass wir an einer gewissen Stelle jeweils stets bei jedem Rerendering die aktuelle Uhrzeit sehen möchten.

Eine ähnliche Funktionalität, ohne React implementiert, hätte stattdessen wohl in etwa so ausgesehen:

```javascript
function changeTime() {
  var time = new Date().toLocaleTimeString();
  var target = document.getElementById('root');
  target.textContent = 'Es ist jetzt ' + time + ' Uhr';
}
setInterval(changeTime, 1000);
```

Der Vorteil beim **deklarativen** Vorgehen ist, dass wir nur noch **Zustände beschreiben** und sagen, wie etwas angezeigt werden soll und nicht selber jeden Schritt festlegen, wie wir diesen Zielzustand erreichen wollen. Das macht insbesondere bei komplexeren Anwendungen viele Dinge einfacher, übersichtlicher und ist dadurch zugleich deutlich weniger fehleranfälliger.

{% hint style="info" %}
In der Praxis ist es eher üblich, dass `ReactDOM.render()` nur ein einziges Mal, meist beim Öffnen einer Seite aufgerufen wird. Der wiederholte Aufruf der `render()`-Methode dient hier nur zur Veranschaulichung wie **ReactDOM** und **React-Elemente** zusammenspielen.

Das Rerendering lösen dann meist **Komponenten** aus, indem sich ihr State ändert oder ihnen von außen neue Props hereingereicht werden. Mit Komponenten geht es im nächsten Kapitel weiter!
{% endhint %}
