De React useEffect
Hook is een populaire functie geworden in de React bibliotheek sinds de introductie in versie 16.8. Hiermee kunnen ontwikkelaars neveneffecten uitvoeren, zoals het ophalen van gegevens, het bijwerken van de DOM en het abonneren op gebeurtenissen binnen functionele componenten.
De useEffect
Hook kan echter soms lastig te gebruiken zijn. Een veel voorkomende fout die ontwikkelaars tegenkomen is “React Hook useEffect has a missing dependency. Either include it or remove the dependency array” fout.
In dit artikel bespreken we de oorzaken van deze fout en geven we verschillende oplossingen om deze op te lossen.
Wat veroorzaakt de “React Hook useEffect Has a Missing Dependency” fout?
De fout “React Hook useEffect has a missing dependency” treedt op wanneer de useEffect
Hook een dependency-array heeft die onvolledig is of ontbreekt.
De dependency-array is het tweede argument in de useEffect
Hook en wordt gebruikt om de variabelen te specificeren waarvan het effect afhankelijk is. Dit betekent dat wanneer een van de waarden van de variabelen in de dependency-array verandert, het effect opnieuw wordt uitgevoerd.
In een situatie waarin een variabele waarvan het effect afhankelijk is niet is opgenomen in de dependency-matrix, wordt het effect mogelijk niet opnieuw uitgevoerd als de waarde verandert. Dit kan leiden tot onverwacht gedrag en bugs in je applicatie.
Deze fout is geen React fout, maar een ESLint fout. ESLint biedt een plugin speciaal voor React, die een set regels bevat die zijn ontworpen om developers te helpen betere React code te schrijven. Een van deze regels is de "react-hooks/exhaustive-deps"
regel, die de “React Hook useEffect has a missing dependency” fout detecteert.
Laten we als voorbeeld eens kijken naar een functioneel component dat een count state heeft. Van dit component wordt ook verwacht dat het een bericht met de waarde van count
naar de console logt wanneer het verandert:
import { useState, useEffect } from 'react';
const App = () => {
const [count, setCount] = useState(0);
useEffect(() => {
console.log(`You clicked ${count} times`);
}, []);
return (
<div>
<h1>Hello World</h1>
<p>Count: {count}</p>
<button onClick={() => setCount(count + 1)}>Increment</button>
</div>
);
};
export default App;
In het bovenstaande voorbeeld heb je een functioneel component dat de hooks useState
en useEffect
gebruikt. De hook useEffect
wordt gebruikt om een bericht met de waarde van de toestandsvariabele count
te loggen wanneer deze verandert.
Merk echter op dat de count
variabele niet voorkomt in de tweede argumenten array (dependency array) van de useEffect
hook. Dit veroorzaakt de fout “React Hook useEffect has a missing dependency”.
Drie manieren om de “React Hook useEffect Has a Missing Dependency” foutmelding op te lossen
Deze fout kan op verschillende manieren worden opgelost, afhankelijk van de aanpak die je wilt gebruiken. Hier zijn de verschillende manieren.
- Neem alle ontbrekende dependencies op
- Gebruik memoization hooks bij het werken met objecten en functies
- Schakel de ESLint regel uit
1. De ontbrekende dependency toevoegen aan de useEffect dependency-array
De meest voor de hand liggende manier om deze fout op te lossen is door alle dependencies die gebruikt worden in de useEffect
hook op te nemen in de dependency array. Dan kun je je afvragen hoe ken ik een dependency?
Om een ontbrekende dependency te identificeren, moet je kijken naar de variabelen of waarden die worden gebruikt in de useEffect
hook. Als deze variabelen of waarden in de loop van de tijd kunnen veranderen, dan moeten ze worden opgenomen in de dependencymatrix.
In het eerder gegeven codefragment wordt de variabele count
bijvoorbeeld gebruikt in de hook useEffect
, maar deze is niet opgenomen in de dependencymatrix. Dit betekent dat als de count
variabele verandert, de useEffect
ook niet opnieuw wordt uitgevoerd en het component verouderde gegevens of andere problemen kan hebben.
Om deze fout op te lossen, kunnen we de variabele count
toevoegen aan de dependencymatrix, zoals dit:
import { useState, useEffect } from 'react';
const App = () => {
const [count, setCount] = useState(0);
useEffect(() => {
console.log(`You clicked ${count} times`);
}, [count]);
return (
<div>
<h1>Hello World</h1>
<p>Count: {count}</p>
<button onClick={() => setCount(count + 1)}>Increment</button>
</div>
);
};
export default App;
Door de variabele count
toe te voegen aan de dependency-array, vertellen we React om de hook useEffect
opnieuw uit te voeren wanneer de count-variabele verandert.
Dit zorgt ervoor dat het component altijd actuele gegevens heeft en voorkomt de fout “React Hook useEffect has a missing dependency”.
Als je meer dan één dependency hebt, voeg ze dan toe aan de dependency-array en scheid ze met een komma:
import { useState, useEffect } from 'react';
const App = () => {
const [firstName, setFirstName] = useState('');
const [lastName, setLastName] = useState('');
const [fullName, setFullName] = useState('');
useEffect(() => {
setFullName(`${firstName} ${lastName}`);
}, [firstName, lastName]);
const handleFirstNameChange = (event) => {
setFirstName(event.target.value);
};
const handleLastNameChange = (event) => {
setLastName(event.target.value);
};
return (
<div>
<label>
First Name:
<input type="text" value={firstName} onChange={handleFirstNameChange} />
</label>
<label>
Last Name:
<input type="text" value={lastName} onChange={handleLastNameChange} />
</label>
<p>Full Name: {fullName}</p>
</div>
);
};
export default App;
2. Werken met objecten en functies
Als je met objecten en arrays werkt, is het niet genoeg om ze toe te voegen aan je dependency-array. Je wil ze ook memoïseren of verplaatsen naar de useEffect
hook of buiten het component om onnodige re-renders te voorkomen.
Dit komt omdat in JavaScript objecten en arrays worden vergeleken met referenties en elke keer naar een andere locatie in het geheugen wijzen – de waarde ervan zal bij elke render veranderen, wat een oneindige re-render loop veroorzaakt.
Hier is een voorbeeld dat de fout veroorzaakt:
import { useState, useEffect } from 'react';
const App = () => {
const [user, setUser] = useState({});
// 👇️this will change on every render
let newUser = { name: 'Jane', age: 28 };
useEffect(() => {
setUser(newUser);
}, [newUser]);
return (
<div>
<h1>Hello World</h1>
</div>
);
};
export default App;
Je kunt deze fout oplossen door het object te verplaatsen naar de useEffect
hook of door het buiten het component te plaatsen:
import { useState, useEffect } from 'react';
const App = () => {
const [user, setUser] = useState({});
useEffect(() => {
let newUser = { name: 'Jane', age: 28 };
setUser(newUser);
}, []);
return (
<div>
<h1>Hello World</h1>
</div>
);
};
export default App;
Een betere manier om dit probleem op te lossen is door memoization hooks te gebruiken zoals useMemo
voor je object en useCallback
voor functies. Dit zal je helpen om het object of de functie binnen het component en in de dependency-array te houden.
Opmerking: Memoization hooks zijn een verzameling hooks waarmee je de resultaten van complexe berekeningen in de cache kunt opslaan en onnodig herberekenen kunt voorkomen.
Zo ziet je code eruit als je de useMemo
hook gebruikt om je object te memoïseren:
import { useState, useEffect, useMemo } from 'react';
const App = () => {
const [user, setUser] = useState({});
const newUser = useMemo(() => {
return { name: 'John', age: 30 };
}, []);
useEffect(() => {
setUser(newUser);
}, [newUser]);
return (
<div>
<h1>Hello World</h1>
</div>
);
};
export default App;
Op dezelfde manier kun je de useCallback
hook gebruiken als je met functies werkt.
3. De ESLint regel uitschakelen
De “React Hook useEffect has a missing dependency” fout is een ESLint waarschuwingsfout – wat betekent dat we de regel kunnen uitschakelen zodat deze de fout niet wordt gegeven. Deze aanpak wordt niet in alle gevallen aanbevolen, maar het kan een snelle oplossing zijn als je zeker weet dat de ontbrekende dependency geen probleem is.
Dit kan worden gedaan door het volgende commentaar toe te voegen voor de regel van de dependency-array.
// eslint-disable-next-line react-hooks/exhaustive-deps
Hier is een voorbeeld:
useEffect(() => {
console.log(`You clicked ${count} times`);
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
Het is belangrijk om op te merken dat het uitschakelen van de ESLint regel kan leiden tot andere problemen in de toekomst als je niet voorzichtig bent. Zorg ervoor dat je de gevolgen van het uitschakelen van een regel goed begrijpt voordat je het doet en overweeg alternatieve oplossingen als dat mogelijk is.
Samenvatting
De fout “React Hook useEffect has a missing dependency” is een veelvoorkomend probleem waar React ontwikkelaars mee te maken krijgen als ze werken met de useEffect hook.
Bij het oplossen van de fout is het belangrijk om de beste methoden voor jouw specifieke toepassing te overwegen. Over het algemeen kun je het uitschakelen van de ESLint regel die de fout veroorzaakt het beste vermijden, omdat dit in de toekomst tot andere problemen kan leiden. Probeer in plaats daarvan het probleem op te lossen door de ontbrekende dependency op te nemen in de dependency array of door de juiste memoization hook te gebruiken.
Nu is het jouw beurt: Ben jij dit probleem ooit tegengekomen? Hoe heb je het opgelost? Zijn er nog andere benaderingen die je hebt gebruikt die niet in dit artikel zijn behandeld? Laat het ons weten in de comments!