Functional Component — is een manier om React-componenten te maken met gewone JavaScript-functies, die standaard werd na de release van React 16.8 en de komst van hooks. Functionele componenten accepteren props en retourneren React-elementen, zonder overerving van React.Component. Volgens gegevens van React, 2024 wordt 97% van de nieuwe componenten in het React-ecosysteem als functies geschreven.
Belangrijkste punten
Functional Component (functionele component) — is een React-component gedefinieerd als een functie die een props-object accepteert en een React-element retourneert. Vóór React 16.8 werden dergelijke componenten stateless (zonder toestand) genoemd, omdat ze geen interne toestand konden beheren.
Met de komst van hooks in React 16.8 (februari 2019) kregen functionele componenten toegang tot toestand (useState), neveneffecten (useEffect), context (useContext) en referenties (useRef). De term „stateless" is verouderd — moderne functionele componenten beheren de toestand volledig.
React beveelt officieel functionele componenten aan als de primaire manier om componenten te maken. Alle documentatie op react.dev, voorbeelden, tutorials en nieuwe API's (Server Components, Actions) zijn gebaseerd op de functionele benadering. Klasse-componenten zijn niet verwijderd, maar nieuwe React-functionaliteiten zijn alleen via hooks beschikbaar.
De eenvoudigste functionele component — een functie die JSX retourneert. Het accepteert props als argument, vereist geen constructor, super-aanroep of this-binding. Props zijn direct beschikbaar via het functieargument — geen this.props.
// Functional component without state
function Greeting({ name }) {
return <h1>Hello, {name}!</h1>;
}
// Arrow function (common variant)
const Greeting = ({ name }) => (
<h1>Hello, {name}!</h1>
);
Gebruik useState om toestand toe te voegen. De hook retourneert een tuple van twee waarden: de huidige toestand en een setter-functie. In tegenstelling tot this.setState in klassen, vervangt useState de waarde volledig, zonder deze samen te voegen met de vorige.
import React, { useState } from 'react';
function Counter() {
const [count, setCount] = useState(0);
return (
<div>
<p>You clicked {count} times</p>
<button onClick={() => setCount(count + 1)}>
Increment
</button>
</div>
);
}
Hooks vormen de basis van modern React. Elke hook lost een specifieke taak op: useState — toestand, useEffect — neveneffecten, useContext — toegang tot context, useRef — verwijzingen naar DOM-elementen, useCallback en useMemo — memorisatie.
useEffect vervangt tegelijkertijd componentDidMount, componentDidUpdate en componentWillUnmount. Het eerste argument — een callback met het effect, het tweede — een afhankelijkheden-array. Als de array leeg is, wordt het effect eenmalig uitgevoerd na montage. Als afhankelijkheden zijn opgegeven — bij elke wijziging van een ervan.
import React, { useState, useEffect } from 'react';
function UserData({ userId }) {
const [user, setUser] = useState(null);
useEffect(() => {
let cancelled = false;
fetch(`/api/users/${userId}`)
.then(res => res.json())
.then(data => {
if (!cancelled) setUser(data);
});
// Cleanup - analog of componentWillUnmount
return () => { cancelled = true; };
}, [userId]); // Dependency
return <div>{user?.name}</div>;
}
Het belangrijkste voordeel van functionele componenten — hergebruik van logica via aangepaste hooks. Als in een klasse-component de logica werd gedupliceerd tussen componentDidMount en componentDidUpdate, wordt deze in een functionele component ondergebracht in een aparte functie met het voorvoegsel use. Aangepaste hooks zijn het belangrijkste alternatief voor HOC en render props.
React beveelt compositie aan in plaats van overerving voor het hergebruik van code tussen componenten. Functionele componenten zijn ideaal voor compositie: één component kan meerdere andere bevatten en props en children aan hen doorgeven.
Het children-patroon — wanneer een component onderliggende elementen ontvangt via de prop children — wordt op natuurlijke wijze geïmplementeerd: function Layout({ children }). Het equivalent van slots uit Vue wordt geïmplementeerd via benoemde props-componenten: function Page({ header, sidebar, content }).
Overerving wordt in React praktisch niet gebruikt. Zelfs klasse-componenten, die technisch extends ondersteunen, vormen zelden hiërarchieën dieper dan één niveau. Functionele componenten met compositie dekken de behoeften aan codehergebruik volledig zonder overerving.
Functionele componenten hebben ingebouwde optimalisatiemechanismen. React.memo — het equivalent van PureComponent voor functies: voorkomt opnieuw renderen als props niet zijn veranderd (oppervlakkige vergelijking). useMemo cachet het resultaat van berekeningen tussen renders.
import React, { useMemo } from 'react';
// React.memo - memoize component
const ExpensiveList = React.memo(({ items }) => {
return <ul>
{items.map(item =>
<li key={item.id}>{item.name}</li>
)}
</ul>;
});
// useMemo - caching result
function Dashboard({ transactions }) {
const summary = useMemo(() => {
return transactions.reduce((acc, t) => acc + t.amount, 0);
}, [transactions]);
return <p>Total: {summary}</p>;
}
useCallback memoriseert callback-functies zodat ze niet opnieuw worden gemaakt bij elke render. Dit is cruciaal bij het doorgeven van functies aan onderliggende componenten die in React.memo zijn verpakt: zonder useCallback zal de onderliggende component elke keer opnieuw renderen, omdat de verwijzing naar de functie verandert.
Het verschil tussen de benaderingen gaat verder dan syntaxis. Functionele componenten — zijn een sluiting: toestand en effecten zijn gebonden aan een specifieke render. Klasse-componenten — zijn this: toestand wordt altijd uit this.state gehaald, die verouderd kan zijn op het moment van uitvoering van een asynchrone callback.
| Aspect | Functioneel | Klasse |
|---|---|---|
| Toestand | useState (geïsoleerd) | this.state + this.setState |
| Effecten | useEffect met afhankelijkheden | componentDidMount + componentDidUpdate |
| Context | useContext | Context.Consumer of static contextType |
| Optimalisatie | React.memo + useMemo | PureComponent + shouldComponentUpdate |
| Logica hergebruik | Aangepaste hooks | HOC / Render props |
| this | Nee | bind in constructor |
Functionele componenten bieden een lineaire uitvoeringsstroom. In een klasse-component is gerelateerde logica vaak verspreid over meerdere levenscyclusmethoden. Bijvoorbeeld, een WebSocket-abonnement wordt ingesteld in componentDidMount en verwijderd in componentWillUnmount. In een functionele component bevinden beide bewerkingen zich in één useEffect met een opschoningsfunctie.
TypeScript werkt met functionele componenten natuurlijker dan met klassen. Typen van props — een interface voor het functieargument. Het type van de geretourneerde waarde — JSX.Element of ReactNode. useState leidt automatisch het type af van de beginwaarde.
import React, { useState } from 'react';
interface ButtonProps {
label: string;
variant?: 'primary' | 'secondary';
onClick: () => void;
}
const Button: React.FC<ButtonProps> =
({ label, variant = 'primary', onClick }) => (
<button
className={`btn btn-${variant}`}
onClick={onClick}
>
{label}
</button>
);
Modern TypeScript maakt het mogelijk om useReducer te typen met gediscrimineerde union-types, Generics in aangepaste hooks en strikte controle van children via React.PropsWithChildren. Functionele componenten met TypeScript bieden volledige typeveiligheid zonder extra abstracties.
Veelgestelde vragen
Functionele componenten zijn eenvoudiger: geen constructor, bind, this en verspreide levenscyclusmethoden. Hooks maken het mogelijk om gerelateerde logica te groeperen. React investeert middelen in de ontwikkeling van hooks, niet van klassen. Server Components en nieuwe functies zijn alleen beschikbaar in functies.
Ja, via useEffect met een timer erin en een opschoningsfunctie voor clearInterval. Let op de sluiting: als u een teller laat tikken, gebruik dan de functionele vorm van setState: setCount(c => c + 1), om niet afhankelijk te zijn van de oude waarde in de sluiting.
Gebruik useRef om de vorige waarde op te slaan. Werk de ref bij in useEffect na elke render. Voor visuele vergelijking helpt de aangepaste hook usePrevious: const prev = usePrevious(value);
React.memo — een HOC voor het memoriseren van een hele component: voorkomt opnieuw renderen als props niet zijn veranderd. useMemo — een hook voor het memoriseren van een specifieke waarde binnen een component: cachet het resultaat van een functie tussen renders op basis van een afhankelijkheden-array.
De eenvoudigste manier — useState met initialisatie van props + useEffect met afhankelijkheid van props voor synchronisatie. Voor zeldzame gevallen beveelt React aan: gebruik een sleutel (key) voor het geforceerd opnieuw aanmaken van de component bij wijziging van invoergegevens.
Samenvatting
We ontwikkelen een mobiele applicatie turnkey
IT Sectr creëert sinds 2017 iOS- en Android-applicaties voor startups en bedrijven. We adviseren u en stellen de beste oplossing voor.
Lees ook