Reputation: 781
I am getting an error in my console,
my JSON is here https://dev.justinblayney.com/wp-content/uploads/2020/12/main-menu.json_.zip
Warning: Each child in a list should have a unique "key" prop.
What displays on my page is (So they are all unique, so WTF react)
KEY: 2429 KEY: 2430 KEY: 3859 KEY: 2421 KEY: 2802 KEY: 2428
On a side note, I'm discovering that using a function is a terrible way to get a JSON file, I also get memory leak warnings and every tutorial I see online uses classes or axios
Check the render method of MyRoutes
. See https://reactjs.org/link/warning-keys for more information.
MyRoutes@http://localhost:3000/react-wordpress-headless/static/js/main.chunk.js:63:81
div
Router@http://localhost:3000/react-wordpress-headless/static/js/0.chunk.js:35747:30
BrowserRouter@http://localhost:3000/react-wordpress-headless/static/js/0.chunk.js:35367:35
App@http://localhost:3000/react-wordpress-headless/static/js/main.chunk.js:94:1
function MyRoutes() {
const [myrt, setMyrt] = useState([]);
useEffect(() => {
fetch("main-menu.json" ,{
headers : {
'Content-Type': 'application/json',
'Accept': 'application/json'
}
})
.then(res => res.json())
.then(json =>{
setMyrt(json.items)}
)
});
return (
<>
{Object.keys(myrt).map((ky, idx)=> (
<>
<h2>KEY: {myrt[ky].ID} </h2>
<Route exact path={`/${myrt[ky].slug}`} component={Page} key={myrt[ky].ID} /></>
))}
</>
);
}
Upvotes: 0
Views: 734
Reputation: 35603
The key
prop should be defined on the first most element, in your case it is React.Fragment
.
function MyRoutes() {
const [myrt, setMyrt] = useState([]);
useEffect(() => {
fetch('main-menu.json', {
headers: {
'Content-Type': 'application/json',
Accept: 'application/json',
},
})
.then((res) => res.json())
.then((json) => {
setMyrt(json.items);
});
});
return (
<>
{Object.keys(myrt).map((ky, idx) => (
<React.Fragment key={ky}>
// ------------^
<h2>KEY: {myrt[ky].ID} </h2>
<Route exact path={`/${myrt[ky].slug}`} component={Page} key={myrt[ky].ID} />
</React.Fragment>
))}
</>
);
}
Upvotes: 3
Reputation: 775
For your memory leak you are calling the function get the JSON file infinite times because you have not specified any dependencies in the useEffect. So you set the data, it rerenders, then fetches again forever
useEffect(() => {
fetch("main-menu.json" ,{
headers : {
'Content-Type': 'application/json',
'Accept': 'application/json'
}
})
.then(res => res.json())
.then(json =>{
setMyrt(json.items)}
)
}, [] /* Adding this only runs this once */);
Upvotes: 1
Reputation: 11
You need the key on the top component/tag that it's rendering on the map. Example: if you use a div
<div key={myrt[ky].ID} >
<h2>KEY: {myrt[ky].ID} </h2>
<Route exact path={`/${myrt[ky].slug}`} component={Page} />
</div>
Upvotes: 1
Reputation: 676
The key
property is needed on the first-level of the list child element, thus I think in your example the React fragment within your .map
needs to have this key.
Upvotes: 1