警告:列表中的每个孩子都应该有一个唯一的“关键”道具。 - 反应JS
Posted
技术标签:
【中文标题】警告:列表中的每个孩子都应该有一个唯一的“关键”道具。 - 反应JS【英文标题】:Warning: Each child in a list should have a unique "key" prop. - ReactJS 【发布时间】:2019-12-07 01:17:48 【问题描述】:我正在使用 ReactJS 构建一个看板应用程序,用户可以将“卡片”添加到三个不同的“列”(Todos、Onprogress 和 Done)。我遇到的问题是应该在卡片中显示的内容没有按应有的方式显示,尽管我的状态正在返回它的对象就好了(当我 console.log 一切时)。我认为问题在于我将一个对象推入一个数组,然后将它作为一个值添加到我的状态键之一,因此,当我使用道具传递它时,我的数据没有被正确读取。我将在下面分享我所有的代码库。
这是我的应用组件:
import React, Component from 'react';
import Column from './Column';
import AddCardForm from './AddCardForm';
import './App.css';
class App extends Component
constructor(props)
super(props)
this.state =
columns: [
name: 'Todos',
cards: []
,
name: 'Onprogress',
cards: []
,
name: 'Done',
cards: []
,
]
;
;
// componentDidMount()
// const coldata = this.state.columns
// console.log(coldata);
// // this.ref = base.syncState();
//
addCard = (card, otherStatus) =>
console.log("Adding a Card");
const cards = ...this.state.columns.cards ;
cards[`card`] = card;
let todosCards = []
let onprogressCards = []
let doneCards = []
Object.values(otherStatus).map(function(value)
if (value.includes('Onprogress') && value.includes('Done'))
todosCards.push(cards)
else if (value.includes('Todos') && value.includes('Done'))
onprogressCards.push(cards);
else if (value.includes('Todos') && value.includes('Onprogress'))
doneCards.push(cards);
return(todosCards || onprogressCards || doneCards);
);
console.log(todosCards);
console.log(onprogressCards);
console.log(doneCards);
this.setState(
columns: [
name: 'Todos',
cards: todosCards
,
name: 'Onprogress',
cards: onprogressCards
,
name: 'Done',
cards: doneCards
,
]
);
render()
return (
<div className="App">
Object.keys(this.state.columns).map(key => (
<Column key=key details=this.state.columns[key] />
))
<AddCardForm addCard=this.addCard />
</div>
);
export default App;
这是我的专栏组件:
import React, Component from "react";
import Card from "./Card"
class Column extends Component
render()
return (
<div className="column">
<h1 className="Title">this.props.details.name</h1>
Object.keys(this.props.details.cards).map( keycard => (
<Card keycard=keycard data=this.props.details.cards[keycard] />
))
</div>
);
export default Column;
这是我的卡片组件:
import React, Component from "react";
class Card extends Component
render()
const taskName, taskDescription, taskPeriod = this.props.data;
// const isTaskOn = taskStatus
return (
<div className="card">
<span className="title">taskName</span>
<div className="description">
<h4>taskDescription</h4>
</div>
<div className="period">
<h4>taskPeriod</h4>
</div>
<div className="status">
<select>
<option value='Todos'>Todos</option>
<option value='Onprogress'>Onprogress</option>
<option value="Done">Done</option>
</select>
</div>
</div>
);
export default Card;
这是我的 AddCardForm 组件:
import React, Component from 'react';
class AddCardForm extends Component
taskName = React.createRef();
taskDescription = React.createRef();
taskPeriod = React.createRef();
taskStatus = React.createRef();
addCardtoApp = event =>
event.preventDefault();
const card =
taskName: this.taskName.current.value,
taskDescription: this.taskDescription.current.value,
taskPeriod: this.taskPeriod.current.value,
;
const cardStatus = this.taskStatus.current.value;
let otherStatus =
otherStatus: this.taskStatus.current.textContent.replace(`$cardStatus`, ''),
;
this.props.addCard(card, otherStatus);
event.currentTarget.reset();
;
render()
return (
<form onSubmit=this.addCardtoApp>
<label>
Task Name:
<input type="text" name="taskName" ref=this.taskName/>
</label> <br />
<label>
Description:
<input type="text" name="taskDescription" ref=this.taskDescription />
</label> <br />
<label>
Period:
<input type="text" name="taskPeriod" ref=this.taskPeriod />
</label> <br />
<label>
Task Status:
<select type="text" name="taskStatus" ref=this.taskStatus>
<option value="Todos">Todos</option>
<option value="Onprogress">Onprogress</option>
<option value="Done">Done</option>
</select>
</label> <br />
<input type="submit" value="Submit" />
</form>
);
export default AddCardForm;
【问题讨论】:
首先阅读key
的工作原理以及为什么需要它reactjs.org/docs/lists-and-keys.html
【参考方案1】:
来自反应文档:
键帮助 React 识别哪些项目已更改、添加或删除。应为数组内的元素赋予键,以使元素具有稳定的身份
因此,本质上,如果您将数组映射到组件,则为每个组件(映射的)拥有唯一的键将确保仅在必要时重新渲染这些组件。
请关注this documentation,您将了解警告想要深入告诉您的内容。
【讨论】:
【参考方案2】:您在使用循环构建 React 组件的任何地方都必须添加 prop key
并为其传递一个唯一值。
您可以像这样重新定义您的 map
调用以包含索引:
Object.keys(this.state.columns).map((count, key) => (
<Column key=count details=this.state.columns[key] />
))
【讨论】:
以上是关于警告:列表中的每个孩子都应该有一个唯一的“关键”道具。 - 反应JS的主要内容,如果未能解决你的问题,请参考以下文章
如何修复警告:列表中的每个孩子都应该有一个唯一的“关键”道具
添加了关键道具 ||警告:列表中的每个孩子都应该有一个唯一的“关键”道具
React - 警告:列表中的每个孩子都应该有一个唯一的“关键”道具