I'm have trouble figuring out why my li elements don't have their assigned keys in the DOM. I keep getting the "Warning: Each child in a list should have a unique 'key' prop" error even after providing a unique key.
Bear with me as I'm still learning! This is using ReactJS.
This is the component that uses posts (a state variable with an array of objects) and iterates through it, returning the Post component each time, using .map(). Each object within the state array has a content and type property.
I pass the index through as a prop:
import React from "react";
import Post from "./Post";
function PostList({ posts, handleDelete }) {
const postsLi = posts.map((post, index) => {
return (
<Post post={post} postIndex={index} handleDelete={handleDelete} />
)
})
return (
<div className="post-list">
<ul>
{postsLi}
</ul>
</div>
);
}
export default PostList;
Here is the Post component.:
import React, { useState } from "react";
function Post({ post, postIndex, handleDelete }) {
const { content, type } = post;
const textContent = (<p key={`a${postIndex}`}>{content}</p>);
const urlContent = (<img key={`i${postIndex}`} src={content} />)
const finalContent = type === "textarea" ? textContent : urlContent;
//Need to figure out why key attribute isn't showing up
return (
<li key={`post-${postIndex}`} className="post" >
{finalContent}
<br />
<button key={`b${postIndex}`} name="delete" onClick={handleDelete} id={postIndex}>Delete</button>
</li>
)
}
export default Post;
I read on another post that all the children within a li element also needs to have keys, but that did not work either. Post is not considered siblings with PostList, right? Also the button element successfully has an id value of the index, so its being passed into the Post component just fine.
I read on another post that all the children within a li element also need to have keys, but that did not work either.
Maybe you have read this article: https://sentry.io/answers/unique-key-prop/
When creating a list in the UI from an array with JSX, you should add a key prop to each child and to any of its’ children.
Ex:
<li key="uniqueId1" >Item1</li>
React uses the key prop create a relationship between the component and the DOM element. The library uses this relationship to determine whether or not the component should be re-rendered.
It is not recommended to use the index of the array as the key prop if you know the array will not be static. If the key is an index, reordering an item in the array changes it. Then React will get confused and re-render the incorrect element.
Keys do not have to be unique globally. They just need to be unique across sibling elements.
In your case, you want to use the index as key key={index}
in your Post element, not sure if your array will not be static (as mentioned above).
const postsLi = posts.map((post, index) => {
return (
<Post key={key} post={post} postIndex={index} handleDelete={handleDelete} />
)
})
Add a key to this statement and I think it would fix that error:
const postsLi = posts.map((post, index) => {
return (
<Post key={"some unique key" or index} post={post} postIndex={index} handleDelete={handleDelete} />
)
})