Reputation: 101
This is my component:
import React, { useState, useEffect } from "react";
export default function App() {
const [countriesArray, setCountriesArray] = useState([]);
useEffect(() => {
getCountriesArray();
}, []);
const getCountriesArray = async () => {
try {
let response = await fetch(
"https://coronavirus-19-api.herokuapp.com/countries"
);
if (response.status === 200) {
const newCountriesArray = [...countriesArray];
const data = await response.json();
await data.forEach(item => newCountriesArray.push(item.country));
setCountriesArray(newCountriesArray);
} else {
setErrorStatus(true);
console.error("Error status");
}
} catch (err) {
console.error(err);
}
};
const optionItems = countriesArray.map((item) =>
<option key={item}>{item}</option>
)
return (
<div className="App">
<select>{optionItems}</select>
</div>
);
}
In the select I get the names of the countries when mounting the component but in the console I have a loop error message:
Warning: Encountered two children with the same key, `Total:`. Keys should be unique so that components maintain their identity across updates. Non-unique keys may cause children to be duplicated and/or omitted — the behavior is unsupported and could change in a future version.
in select (at App.js:36)
in div (at App.js:35)
in App
in StrictMode (at src/index.js:8)
However I use the empty array as a second parameter of the useEffect to execute it only when mounting the component
Upvotes: 0
Views: 410
Reputation: 84982
That error has nothing to do with the the effect's dependency array. The problem is that item.country is not unique in that data. The json includes 7 entries where country
=== "Total:"
.
A couple possibilities:
1) Filter out the duplicates. This is best if you don't care about those "Total:" entries.
if (response.status === 200) {
const newCountriesArray = [...countriesArray];
const data = await response.json();
data.forEach(item => {
if (item.country !== "Total:") {
newCountriesArray.push(item.country)
}
});
setCountriesArray(newCountriesArray);
}
2) Use a different key. Since this data does not have a unique key, you may need to use the index of the array. Be aware that this will not be a good option if you plan to sort this list.
const optionItems = countriesArray.map((item, index) =>
<option key={index}>{item}</option>
)
Upvotes: 1
Reputation: 1805
You can use the key provided by the map itself this way:
const optionItems = countriesArray.map((item, key) =>
<option key={key}>{item}</option>
)
That should solve your problem.
By the way, this is not an infinite loop problem, it is a duplicate key in you map function.
Upvotes: 1