Ga naar hoofdinhoud

Beginnen met React: componenten, props en state

In het vorige hoofdstuk zag je een overzicht van de populairste frameworks. Nu gaan we dieper in op React: het meest gebruikte frontend framework ter wereld. Je leert hoe je een project aanmaakt, hoe componenten werken en hoe je data beheert met state.

Waarom React?

React is gebouwd door Meta (Facebook) en is in 2013 uitgebracht. Sindsdien is het uitgegroeid tot het dominante frontend framework: het heeft het grootste ecosysteem, de meeste beschikbare bibliotheken en de meeste vacatures. Als je met React leert werken, open je een grote deur op de arbeidsmarkt.

React of iets anders?

Vue is toegankelijker voor absolute beginners. Maar als je snel wil starten met een framework dat overal gevraagd wordt, is React een uitstekende keuze.

Je eerste React-project aanmaken

We gebruiken Vite om het project op te zetten. Vite is een snelle build-tool die je project klaar maakt om in de browser te draaien. Voer deze commando's uit in je terminal:

Terminal
npm create vite@latest my-app -- --template react
cd my-app
npm install
npm run dev

Na npm run dev opent Vite een lokale server. Ga naar http://localhost:5173 in je browser en je ziet de standaard React-startpagina.

De projectstructuur

Na het aanmaken zie je deze bestanden:

my-app/
index.html ← het HTML-bestand dat de browser laadt
src/
main.jsx ← het startpunt: koppelt React aan index.html
App.jsx ← het hoofdcomponent van je applicatie

index.html bevat één <div id="root">. React vult die div met jouw componenten. In main.jsx staat de koppeling:

src/main.jsx
import { StrictMode } from 'react'
import { createRoot } from 'react-dom/client'
import App from './App.jsx'

createRoot(document.getElementById('root')).render(
<StrictMode>
<App />
</StrictMode>
)

Je hoeft dit bestand zelden aan te passen. Je werk speelt zich af in App.jsx en de componenten die je zelf aanmaakt.

Componenten

Een component is een herbruikbaar stukje gebruikersinterface. Het is een JavaScript-functie die JSX teruggeeft. Componenten beginnen altijd met een hoofdletter.

src/Welcome.jsx
function Welcome() {
return (
<div>
<h1>Welkom bij mijn app!</h1>
<p>Dit is mijn eerste React-component.</p>
</div>
)
}

export default Welcome

Importeer en gebruik dit component in App.jsx:

src/App.jsx
import Welcome from './Welcome.jsx'

function App() {
return (
<div>
<Welcome />
<Welcome />
</div>
)
}

export default App

Je ziet nu twee keer hetzelfde welkomstblok op de pagina. Dat is de kracht van herbruikbaarheid.

JSX

JSX is de HTML-achtige syntax die je in React-componenten schrijft. Het lijkt op HTML, maar het is eigenlijk JavaScript. De browser begrijpt JSX niet rechtstreeks; Vite zet het automatisch om naar gewoon JavaScript.

Er zijn drie belangrijke regels:

1. Altijd één root-element. Een component mag maar één wrapper-element teruggeven. Gebruik een lege tag <>...</> als je geen extra div wil:

src/Example.jsx
function Example() {
return (
<>
<h2>Titel</h2>
<p>Paragraaf</p>
</>
)
}

2. Gebruik className in plaats van class. In JSX is class een gereserveerd woord in JavaScript. Schrijf altijd className:

src/Button.jsx
function Button() {
return <button className="btn-primary">Klik hier</button>
}

3. JavaScript-expressies schrijf je tussen {}:

src/Greeting.jsx
const name = 'Anna'

function Greeting() {
return (
<p>
Hallo, {name}! Het is nu {new Date().getFullYear()}.
</p>
)
}

Props

Met props geef je data mee aan een component. Props werken als parameters van een functie. Zo maak je een component flexibel en herbruikbaar.

src/Card.jsx
function Card({ title, description }) {
return (
<div className="card">
<h2>{title}</h2>
<p>{description}</p>
</div>
)
}

export default Card

Gebruik dit component met eigen waarden:

src/App.jsx
import Card from './Card.jsx'

function App() {
return (
<div>
<Card title="Webdesign" description="Mooie interfaces op maat." />
<Card
title="Development"
description="Schaalbare webapplicaties."
/>
</div>
)
}

export default App
Standaardwaarden voor props

Geef een prop een standaardwaarde als die niet altijd verplicht is:

src/Card.jsx
function Card({ title, description = 'Geen beschrijving opgegeven.' }) {
return (
<div className="card">
<h2>{title}</h2>
<p>{description}</p>
</div>
)
}

State met useState

State is data die kan veranderen, zoals de waarde van een invoerveld of de score in een spel. Wanneer state verandert, hertekent React het component automatisch.

Je beheert state met de useState-hook:

src/Counter.jsx
import { useState } from 'react'

function Counter() {
const [count, setCount] = useState(0)

return (
<div>
<p>Aantal klikken: {count}</p>
<button onClick={() => setCount(count + 1)}>Klik!</button>
</div>
)
}

export default Counter

useState(0) geeft twee dingen terug: de huidige waarde (count) en een functie om die waarde te updaten (setCount). Elke keer dat je setCount aanroept, hertekent React het component met de nieuwe waarde.

Waarom geen gewone variabele?

Als je let aantal = 0 gebruikt en de waarde aanpast, weet React niet dat er iets is veranderd. Alleen via useState triggert een update de hertekening van het component.

Lijsten renderen

Gebruik .map() om een array van items om te zetten naar JSX-elementen. Elk item heeft een key-prop nodig: React gebruikt die om bij te houden welk element welk is.

src/FruitList.jsx
const fruits = ['Appel', 'Banaan', 'Kers']

function FruitList() {
return (
<ul>
{fruits.map((item) => (
<li key={item}>{item}</li>
))}
</ul>
)
}

export default FruitList
De key-prop

Gebruik een unieke, stabiele waarde als key: een ID uit je database is ideaal. Gebruik zo min mogelijk de index van het array als sleutel, want dat kan problemen geven als de volgorde van items verandert.

Een volledig voorbeeld

Hier is een kleine takenlijst die componenten, props, state en lijsten samenvoegt:

src/TaskItem.jsx
function TaskItem({ text, done, onClick }) {
return (
<li
onClick={onClick}
style={{
textDecoration: done ? 'line-through' : 'none',
cursor: 'pointer',
}}
>
{text}
</li>
)
}

export default TaskItem
src/TaskList.jsx
import { useState } from 'react'
import TaskItem from './TaskItem.jsx'

const initialTasks = [
{ id: 1, text: 'HTML leren', done: true },
{ id: 2, text: 'CSS leren', done: true },
{ id: 3, text: 'React leren', done: false },
]

function TaskList() {
const [tasks, setTasks] = useState(initialTasks)

function toggleDone(id) {
setTasks(
tasks.map((task) =>
task.id === id ? { ...task, done: !task.done } : task
)
)
}

return (
<div>
<h2>Mijn taken</h2>
<ul>
{tasks.map((task) => (
<TaskItem
key={task.id}
text={task.text}
done={task.done}
onClick={() => toggleDone(task.id)}
/>
))}
</ul>
<p>
{tasks.filter((t) => t.done).length} van {tasks.length} taken
afgerond.
</p>
</div>
)
}

export default TaskList

Gebruik TaskList in App.jsx:

src/App.jsx
import TaskList from './TaskList.jsx'

function App() {
return (
<div
style={{
maxWidth: '480px',
margin: '2rem auto',
fontFamily: 'system-ui',
}}
>
<h1>React takenlijst</h1>
<TaskList />
</div>
)
}

export default App

Klik op een taak om hem af te strepen. React hertekent de lijst automatisch elke keer dat de state verandert.

Volgende stap

Je kent nu de kern van React: componenten, JSX, props, state en lijsten. De logische volgende stap is Next.js: een framework gebouwd bovenop React dat server-side rendering, bestandsgebaseerde routing en een ingebouwde API-laag toevoegt. Next.js is de standaard keuze voor productie-klare React-applicaties.

Kop koffie nodig?

Probeer De Koffiejongens met 50% korting op je bestelling. Geteeld door boeren die met de natuur werken en eerlijk betaald krijgen.