20210902 - React Hook useEffect has a missing dependency 'countries'.
2021-09-02 00:00:00

webpackHotDevClient.js:138 src\App.js
Line 18:6: React Hook useEffect has a missing dependency: ‘countries’. Either include it or remove the dependency array react-hooks/exhaustive-deps

App.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
import axios from "axios";
import React, { useState, useEffect} from "react";

const App = ({countries}) => {
const [countries, setCountries] = useState([])
const [search, setSearch] = useState('')

useEffect(() => {
console.log('effect')
axios
.get('https://restcountries.eu/rest/v2/all')
.then(response => {
console.log('promise fulfilled')
console.log(response)
setCountries(response.data)
// countries.push(response.data) // wrong! you should use setCountries
})
}, []) // If the second parameter is an empty array [], then the effect is only run along with the first render of the component. (It just renders the component only once like componentDidMount.)
console.log('render', countries.length, 'countries')

const handleSearchChange = (event) => {
setSearch(event.target.value)
// console.log(search)
}

const searchCountry = search
? countries.filter(country =>
country.name.toLowerCase().includes
(search.toLowerCase())
)
: []

return (
<div>
find countries: <input
value={search} onChange={handleSearchChange}
/>
{searchCountry.map(country =>
<div key={country.name}>{country.name}</div>
)}
</div>
)
}

export default App;

index.js

1
2
3
4
5
6
7
8
9
10
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';

const countries = []

ReactDOM.render(
<App countries={countries} />,
document.getElementById('root')
);

Note:

Don’t directly mutate a state in React

I attempted to replace useState() with Array.push(). But it didn’t work and instead threw these two errors:

Untitled

For more details:

Why can’t I directly modify a component’s state, really?

useEffect()

Because useEffect is run after the render of the component, where you can find this rule by the prints below:

Untitled

However, with useState(), it will re-render the component and its state countries will be updated to 250 elements and maintain what it have (re-renders caused by other states won’t affect its value due to the state is somewhat independent?), and because we add the second parameter [] of useEffect, now it is just run after the first render of the component.

And here’s a good article introducing how useEffect and its parameters work.

React.js - How to execute useEffect hook only once?