Du startest bei den Grundlagen des Webs und endest bei einer kleinen Seite, die auf deine Eingaben reagiert. Kein React-Vorwissen nötig, ein bisschen Gefühl für HTML reicht.
Weiter mit der Pfeiltaste → oder dem Button unten.
Bei Endress+Hauser dreht sich alles um Messtechnik. Sensoren erfassen Daten, Software macht sie sichtbar und nutzbar. Am Ende dieses Kurses hast du selbst so eine kleine Software gebaut, die Messwerte aufnimmt und auswertet.
Diese Präsentation führt dich Schritt für Schritt. Jede Folie bringt genau einen Gedanken. Erst das Konzept dahinter, dann der Code, dann das nächste Stück.
Bevor React ins Spiel kommt, musst du wissen, worauf es aufsetzt. Jede Seite im Netz besteht aus drei Schichten, die zusammenspielen.
Der Browser liest diese drei Teile und baut daraus das Bild auf deinem Schirm zusammen.
Nur HTML, sonst nichts. Eine Überschrift und ein Button.
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8" />
<title>Meine Seite</title>
</head>
<body>
<h1>Hallo Welt!</h1>
<button>Klick mich</button>
</body>
</html>Der Button lässt sich anklicken, aber es passiert nichts. Die Logik fehlt. Genau hier stellt sich die Frage, die zu React führt.
Stell dir eine Seite mit einem Zähler vor. Bei jedem Klick müsstest du von Hand die richtige Textstelle im Dokument suchen und überschreiben. Bei zehn solchen Stellen wird das schnell unübersichtlich und fehleranfällig.
Man nennt diese Handarbeit imperativ: Du beschreibst jeden einzelnen Schritt der Änderung.
React ist eine JavaScript-Bibliothek, ursprünglich bei Meta entstanden. Sie übernimmt den dritten Baustein, das lebendige Verhalten, sobald eine Seite viele wechselnde Zustände hat.
Zustand rein, Oberfläche raus. Ändere den Zustand, und React zeichnet neu.
In React arbeitest du mit Komponenten. Eine Komponente ist ein wiederverwendbarer Baustein: ein Button, eine Messkarte oder eine ganze Seite.
Denk an Lego. Du baust einen Stein einmal und steckst ihn beliebig oft zusammen. Große Oberflächen entstehen so aus vielen kleinen, überschaubaren Teilen. Das macht den Code lesbar und wartbar.
Mehr zu Komponenten bei W3SchoolsFür den Einstieg reichen ein Editor und ein Browser. Wir nutzen Visual Studio Code und laden React direkt aus dem Netz, ganz ohne Installation von Zusatzwerkzeugen.
code.visualstudio.com und installiere es.react-kurs.index.html.Kopiere diesen Code in index.html und speichere mit Strg + S.
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Mein erstes React</title>
</head>
<body>
<!-- Hier landet später unsere Oberfläche -->
<div id="root"></div>
<!-- React selbst -->
<script src="https://unpkg.com/react@18/umd/react.development.js" crossorigin></script>
<script src="https://unpkg.com/react-dom@18/umd/react-dom.development.js" crossorigin></script>
<!-- Babel übersetzt JSX direkt im Browser -->
<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
<!-- Unser eigener Code -->
<script type="text/babel">
function App() {
return <h1>Hallo React</h1>;
}
ReactDOM.createRoot(document.getElementById("root")).render(<App />);
</script>
</body>
</html>Die Erweiterung Live Server aktualisiert den Browser automatisch, sobald du speicherst. Kein ständiges Neuladen von Hand.
index.html, dann Open with Live Server.http://127.0.0.1:5500.Eine Komponente ist eine normale JavaScript-Funktion, die zurückgibt, was angezeigt werden soll. Der Name beginnt groß, das unterscheidet deine Bausteine von einfachen HTML-Tags.
function Gruss() {
return <p>Willkommen im Kurs.</p>;
}
function App() {
return (
<div>
<h1>Startseite</h1>
<Gruss />
<Gruss />
</div>
);
}Die Funktion App nutzt Gruss gleich zweimal. Einmal bauen, oft verwenden.
Dir ist sicher aufgefallen: mitten im Code steht etwas, das wie HTML aussieht. Das ist JSX. Es lässt dich Struktur und Logik an einem Ort schreiben, statt beides mühsam getrennt zu halten.
Mit geschweiften Klammern holst du JavaScript-Werte direkt in die Anzeige.
function App() {
const name = "Max";
const jahr = 2026;
return (
<div>
<h1>Hallo {name}</h1>
<p>Wir schreiben das Jahr {jahr}.</p>
<p>In zwei Jahren ist {jahr + 2}.</p>
</div>
);
}class ist in JavaScript schon vergeben, deshalb schreibt man in JSX className.div.Merkst du dir diese zwei Dinge, ersparst du dir die häufigsten Fehlermeldungen am Anfang.
JSX-Regeln bei W3SchoolsEin Baustein wird erst nützlich, wenn du ihn anpassen kannst. Die Werte, die du einer Komponente von außen mitgibst, heißen Props, kurz für properties.
Denk an eine Funktion, der du Argumente übergibst. Genau so funktionieren Props: dieselbe Komponente, andere Werte, anderes Ergebnis.
function Messkarte(props) {
return (
<div>
<h2>{props.titel}</h2>
<p>Aktueller Wert: {props.wert} {props.einheit}</p>
</div>
);
}
function App() {
return (
<div>
<Messkarte titel="Temperatur" wert={21.5} einheit="°C" />
<Messkarte titel="Druck" wert={1013} einheit="hPa" />
</div>
);
}Dieselbe Messkarte zeigt einmal Temperatur, einmal Druck. Nur die Werte wechseln.
Du kannst die Props direkt in den geschweiften Klammern auspacken. Das spart das ständige props. davor.
function Messkarte({ titel, wert, einheit }) {
return (
<div>
<h2>{titel}</h2>
<p>Aktueller Wert: {wert} {einheit}</p>
</div>
);
}Beide Schreibweisen tun dasselbe. Die kürzere siehst du in fast jedem echten Projekt.
Props kommen von außen und ändern sich für die Komponente nicht. Aber was, wenn eine Komponente sich selbst etwas merken soll, etwa wie oft ein Button gedrückt wurde?
Dafür gibt es State, den inneren Zustand. Ändert sich der State, zeichnet React die Komponente automatisch neu. Genau das macht eine Seite lebendig.
useState bei W3SchoolsEine normale Variable funktioniert hier nicht. React merkt die Änderung nicht.
function Zaehler() {
let anzahl = 0; // normale Variable, React merkt Änderungen NICHT
function hoch() {
anzahl = anzahl + 1;
console.log(anzahl); // steigt in der Konsole, Seite bleibt stehen
}
return <button onClick={hoch}>Klicks: {anzahl}</button>;
}Die Zahl steigt in der Konsole, die Seite bleibt aber stehen. Es fehlt der Weg, React über die Änderung zu informieren.
const { useState } = React;
function Zaehler() {
const [anzahl, setAnzahl] = useState(0);
function hoch() {
setAnzahl(anzahl + 1);
}
return <button onClick={hoch}>Klicks: {anzahl}</button>;
}useState(0) startet bei null und gibt dir zwei Dinge: den Wert anzahl und die Funktion setAnzahl. Rufst du setAnzahl auf, zeichnet React neu.
set-Funktion nutzen.Ereignisse verbinden Nutzer und Code. Einen Klick fängst du mit onClick ab, eine Tastatureingabe mit onChange.
function Eingabefeld() {
const [text, setText] = useState("");
return (
<div>
<input
value={text}
onChange={(e) => setText(e.target.value)}
placeholder="Schreib etwas"
/>
<p>Du hast getippt: {text}</p>
</div>
);
}Bei jedem Tastendruck speichert setText den neuen Wert, und der Absatz darunter zeigt ihn sofort. Eingabe und Anzeige bleiben im Gleichschritt.
Selten steht die Zahl der Einträge vorher fest. Statt jede Zeile zu tippen, lässt du React die Liste aus deinen Daten bauen. Das Werkzeug heißt map.
function Liste() {
const staedte = ["Weil am Rhein", "Lörrach", "Basel"];
return (
<ul>
{staedte.map((stadt, index) => (
<li key={index}>{stadt}</li>
))}
</ul>
);
}Das key-Attribut gibt jedem Element eine eindeutige Kennung, damit React Änderungen sauber zuordnet. Ohne key beschwert es sich zu Recht.
Endress+Hauser baut Messgeräte, die in Fabriken und Anlagen rund um die Uhr Temperatur, Druck oder Durchfluss erfassen. Aus solchen Zahlenreihen entstehen Entscheidungen, ob ein Prozess sauber läuft oder nachgeregelt werden muss.
Genau dieses Prinzip baust du jetzt im Kleinen nach. Deine Seite nimmt Temperaturwerte auf, sammelt sie in einer Liste und rechnet den Durchschnitt aus. Ein Mini-Messsystem im Browser.
Wichtig ist die Reihenfolge. Wir zeigen nicht sofort das fertige Programm, sondern bauen es in fünf Etappen auf. Jede Etappe fügt genau ein Stück hinzu.
Zuerst nur die Struktur: Überschrift, Eingabefeld, Knopf. Noch reagiert nichts, aber du siehst, wie die Oberfläche aussehen soll.
const { useState } = React;
function App() {
return (
<div className="app">
<h1>Messwerte-Tracker</h1>
<p>Trage Temperaturwerte ein und behalte den Überblick.</p>
<div className="row">
<input type="number" placeholder="z. B. 21.5" />
<button>Hinzufügen</button>
</div>
</div>
);
}Wie beim echten Messgerät baust du erst das Gehäuse, bevor die Sensorik rein kommt.
Jetzt bekommt das Feld ein Gedächtnis. Mit useState hält die Komponente fest, was gerade getippt wird, und zeigt es sofort darunter an.
function App() {
const [eingabe, setEingabe] = useState("");
return (
<div className="app">
<h1>Messwerte-Tracker</h1>
<div className="row">
<input
type="number"
value={eingabe}
placeholder="z. B. 21.5"
onChange={(e) => setEingabe(e.target.value)}
/>
<button>Hinzufügen</button>
</div>
<p>Aktuelle Eingabe: {eingabe}</p>
</div>
);
}Das ist der erste Sensor: Die Seite nimmt wahr, was du eingibst.
Ein zweiter Speicher hält alle bisherigen Messungen. Der Knopf ruft hinzufuegen auf, prüft die Zahl und hängt sie an die Liste an. Das Feld wird danach geleert.
function App() {
const [eingabe, setEingabe] = useState("");
const [werte, setWerte] = useState([]);
function hinzufuegen() {
const zahl = parseFloat(eingabe);
if (Number.isNaN(zahl)) return; // leere Eingabe ignorieren
setWerte([...werte, zahl]);
setEingabe("");
}
return (
<div className="app">
<h1>Messwerte-Tracker</h1>
<div className="row">
<input
type="number"
value={eingabe}
placeholder="z. B. 21.5"
onChange={(e) => setEingabe(e.target.value)}
/>
<button onClick={hinzufuegen}>Hinzufügen</button>
</div>
<p>Gespeichert: {werte.length} Werte</p>
</div>
);
}Ab hier zählt die Seite mit, wie viele Werte du erfasst hast.
Eine eigene Komponente Messwert stellt eine Zeile dar. Mit map erzeugt React für jeden gespeicherten Wert eine solche Zeile.
function Messwert({ wert, einheit }) {
return (
<li>
<span>Messung</span>
<span>{wert} {einheit}</span>
</li>
);
}
function App() {
const [eingabe, setEingabe] = useState("");
const [werte, setWerte] = useState([]);
function hinzufuegen() {
const zahl = parseFloat(eingabe);
if (Number.isNaN(zahl)) return;
setWerte([...werte, zahl]);
setEingabe("");
}
return (
<div className="app">
<h1>Messwerte-Tracker</h1>
<div className="row">
<input
type="number"
value={eingabe}
placeholder="z. B. 21.5"
onChange={(e) => setEingabe(e.target.value)}
/>
<button onClick={hinzufuegen}>Hinzufügen</button>
</div>
<ul>
{werte.map((w, i) => (
<Messwert key={i} wert={w} einheit="°C" />
))}
</ul>
</div>
);
}Aus einzelnen Zahlen wird eine sichtbare Messreihe, wie das Protokoll eines Sensors.
Zum Schluss die Kennzahl. Der Durchschnitt rechnet sich bei jeder Änderung neu, ganz ohne Knopfdruck. Diese zwei Ergänzungen kommen ins Innere von App.
// im Inneren von App, nach der hinzufuegen-Funktion:
const durchschnitt = werte.length
? (werte.reduce((a, b) => a + b, 0) / werte.length).toFixed(1)
: "0";
// im return, direkt unter der Liste:
<div className="stats">
<span>Anzahl: {werte.length}</span>
<span>Durchschnitt: {durchschnitt} °C</span>
</div>Genau das macht ein Messsystem wertvoll: Es liefert nicht nur Rohdaten, sondern eine Aussage.
Hier steht das komplette Programm am Stück, so wie deine fünf Schritte es ergeben. Alles passt in eine index.html. Speichern, per Live Server öffnen, fertig.
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Messwerte-Tracker</title>
<style>
body { font-family: Arial, Helvetica, sans-serif; margin: 0;
background: #f2f6f9; color: #1b1b1b; }
.app { max-width: 480px; margin: 40px auto; background: #fff;
padding: 24px; border-radius: 10px;
box-shadow: 0 2px 12px rgba(0,0,0,.08); }
h1 { color: #0a2f4a; font-size: 1.4rem; margin-top: 0; }
.row { display: flex; gap: 8px; margin: 16px 0; }
input { flex: 1; padding: 10px; border: 1px solid #cdd8e0;
border-radius: 6px; font-size: 1rem; }
button { background: #009EE3; color: #fff; border: none;
padding: 10px 16px; border-radius: 6px; cursor: pointer;
font-size: 1rem; }
button:hover { background: #007AB8; }
ul { list-style: none; padding: 0; }
li { display: flex; justify-content: space-between; padding: 8px 0;
border-bottom: 1px solid #eef2f5; }
.stats { display: flex; gap: 24px; margin-top: 16px;
color: #0a2f4a; font-weight: bold; }
</style>
</head>
<body>
<div id="root"></div>
<script src="https://unpkg.com/react@18/umd/react.development.js" crossorigin></script>
<script src="https://unpkg.com/react-dom@18/umd/react-dom.development.js" crossorigin></script>
<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
<script type="text/babel">
const { useState } = React;
function Messwert({ wert, einheit }) {
return (
<li>
<span>Messung</span>
<span>{wert} {einheit}</span>
</li>
);
}
function App() {
const [eingabe, setEingabe] = useState("");
const [werte, setWerte] = useState([]);
function hinzufuegen() {
const zahl = parseFloat(eingabe);
if (Number.isNaN(zahl)) return; // leere Eingabe ignorieren
setWerte([...werte, zahl]);
setEingabe("");
}
const durchschnitt = werte.length
? (werte.reduce((a, b) => a + b, 0) / werte.length).toFixed(1)
: "0";
return (
<div className="app">
<h1>Messwerte-Tracker</h1>
<p>Trage Temperaturwerte ein und behalte den Überblick.</p>
<div className="row">
<input
type="number"
value={eingabe}
placeholder="z. B. 21.5"
onChange={(e) => setEingabe(e.target.value)}
/>
<button onClick={hinzufuegen}>Hinzufügen</button>
</div>
<ul>
{werte.map((w, i) => (
<Messwert key={i} wert={w} einheit="°C" />
))}
</ul>
<div className="stats">
<span>Anzahl: {werte.length}</span>
<span>Durchschnitt: {durchschnitt} °C</span>
</div>
</div>
);
}
ReactDOM.createRoot(document.getElementById("root")).render(<App />);
</script>
</body>
</html>Du hast den Bogen von rohem HTML bis zu einer reagierenden React-Seite geschafft. Für den nächsten Schritt lohnen sich drei Dinge: das Aufteilen einer App in mehrere Dateien, das Build-Werkzeug Vite und der Haken useEffect, sobald deine Seite mit einem Server sprechen soll.
Jede Erweiterung übt genau die Bausteine, die du hier gelernt hast.
Du kennst jetzt Komponenten, JSX, Props, State, Events und Listen und hast ein echtes Projekt gebaut.
Der Rest ist Übung...