正在渲染对象数组的数组,不断收到“警告:列表中的每个孩子都应该有一个唯一的“关键”道具。”
Posted
技术标签:
【中文标题】正在渲染对象数组的数组,不断收到“警告:列表中的每个孩子都应该有一个唯一的“关键”道具。”【英文标题】:Was rendering arrays of arrays of objects, keep getting "Warning: Each child in a list should have a unique "key" prop." 【发布时间】:2020-01-10 07:27:02 【问题描述】:我有一个包含数组数组的对象。我能够让它按照我想要的方式渲染。但是,React 键给我带来了麻烦;抛出这个“警告:列表中的每个孩子都应该有一个唯一的“关键”道具。”
我尝试在原始数组对象中为每个数组中的每个元素提供一个唯一的“id”属性,但没有帮助。
我也浏览了这些,但我认为我有所有的建议: Each child in an array or iterator should have a unique "key" prop in reactjs Warning: Each child in a list should have a unique "key" prop Warning: Each child in an array or iterator should have a unique "key" prop. Check the render method of `ListView`
我的对象
const courses =
[
name: 'Half Stack application development',
id: 'Half Stack application development',
parts: [
name: 'Fundamentals of React',
exercises: 10,
id: 'Fundamentals of React'
,
name: 'Using props to pass data',
exercises: 7,
id: 'Using props to pass data'
,
name: 'State of a component',
exercises: 14,
id: 'State of a component'
,
name: 'Redux',
exercises: 11,
id: 'Redux'
]
,
name: 'Node.js',
id: 'Node.js',
parts: [
name: 'Routing',
exercises: 3,
id: 'Routing'
,
name: 'Middlewares',
exercises: 7,
id: 'Middlewares'
]
]
ReactDOM.render(<App course=courses/>, document.getElementById('root'));
这是回调顺序:
应用程序 -> 课程 -> 课程 -> 标题,内容 -> 部分
const App = (course) =>
return (
<>
<Courses course=course />
</>
)
const Courses = (course) =>
console.log("Starting.....")
const courseList = course.map(nameConent => nameConent)
// console.log(courseList)
// const idList = courseList.map(eachCourse =>eachCourse.id)
const mapEverything = () => courseList.map(a => <Course name=a.name partsList=a.parts id=a.id/>)
// const mapEverything = () => courseList.map(a => console.log(a.id))
// console.log("CourseID",idList)
return (
<>
mapEverything()
</>
)
const Course = (name,partsList,id) =>
// console.log(name)
console.log("CourseID", id)
return (
<>
<div key=id>
<Header header=name id=id/>
<Content contents=partsList id=id+"======"/>
</div>
</>
)
const Content = (contents,id) =>
console.log("contentsID",id)
const partList = () => contents.map(part =>
<Part
name=part.name
id=part.id
exercises=part.exercises
/>
)
const getSumofArray = (accumulator, currentValue) => accumulator + currentValue
const exeList = contents.map(content => content.exercises).reduce(getSumofArray)
// console.log(exeList)
return (
<>
<ul key=id>
partList()
</ul>
<b>total exercises: exeList</b>
</>
)
const Header = (header, id) =>
console.log("HeaderID", id)
return (
<>
<h1 key=id>
header
</h1>
</>
)
const Part = (name, id, exercises) =>
console.log("PartID", id)
return (
<>
<li key=id>
name: exercises
</li>
</>
)
课程和内容组件有问题。
警告截图:https://drive.google.com/open?id=1kcLlF0d90BG6LXPojDtfSlBFGafC9HC_
【问题讨论】:
【参考方案1】:这是关键道具的主题。每当我们在 Reactjs 中渲染一个数组或列表时,它都希望有一个可用的键属性。
这个关键属性的存在是出于性能考虑,它使 Reactjs 更容易呈现项目列表。
您所要做的就是为数组中的任何其他元素提供另一个道具。您在课程列表中拥有的最独特的标识符似乎是名称。所以你可能想把你的代码简化成这样的东西来让自己继续前进:
const CourseList = () =>
const RenderedCourses = courses.map(function(course)
return <CourseDetail key=course.name course=course />;
);
return <ul>RenderedCourses</ul>;
;
然后,一旦你开始工作,你就可以用箭头函数和所有的方式使代码简洁:
const CourseList = () =>
const RenderedCourses = courses.map(course => (
<CourseDetail key=course.name course=course />
));
return <ul>RenderedCourses</ul>;
;
【讨论】:
【参考方案2】:我认为这里有问题:
const mapEverything = () => courseList.map(a => <Course name=a.name partsList=a.parts id=a.id/>)
您应该尝试在此处添加密钥:
const mapEverything = () => courseList.map(a => <Course name=a.name partsList=a.parts id=a.id key=a.id/>)
这里也是:
const partList = () => contents.map(part =>
<Part
name=part.name
id=part.id
exercises=part.exercises
key=part.id
/>)
Here 很好地解释了为什么需要这样做。
【讨论】:
你是对的,但请解释一下为什么我们需要key
。
Keys 帮助 React 知道哪些元素是相同的或已更改以重用(或创建新)元素。您可以在文档中阅读更多内容或查看更多示例:reactjs.org/docs/lists-and-keys.html
等等,所以关键不是引用渲染的 HTML,而是 React 的内部?我多次阅读了 reactjs 文档,并认为它需要成为渲染 DOM 的一部分,尽管它是隐藏的。另外,如果您查看我的屏幕截图,所有 Key 的值都能够传递给每个回调组件,为什么我需要显式传递另一个“Key”组件?
@TimothyCumberland 是的,你说得对,React 的内部功能需要它。以上是关于正在渲染对象数组的数组,不断收到“警告:列表中的每个孩子都应该有一个唯一的“关键”道具。”的主要内容,如果未能解决你的问题,请参考以下文章