ReactJS警告:更改组件后遇到两个具有相同键的子级
我创建了一个reactJS应用程序,它有一个主页和一个详细信息页,主页从一个具有字母数字唯一键的数据库中获取数据,一旦我单击详细信息页并呈现详细信息组件,但当我返回主页时ReactJS警告:更改组件后遇到两个具有相同键的子级,reactjs,Reactjs,我创建了一个reactJS应用程序,它有一个主页和一个详细信息页,主页从一个具有字母数字唯一键的数据库中获取数据,一旦我单击详细信息页并呈现详细信息组件,但当我返回主页时警告:遇到两个具有相同键的子项 此密钥来自firebase数据库 我的App.js function App() { return ( <div className="App"> <Router> <Navbar />
警告:遇到两个具有相同键的子项
此密钥来自firebase数据库
我的App.js
function App() {
return (
<div className="App">
<Router>
<Navbar />
<Route path="/" exact component={ExpenseList} />
<Route path="/details/:id" component={ExpenseDetails} />
</Router>
</div>
);
}
函数应用程序(){
返回(
);
}
我的主页组件tran变量设置为全局变量
import React, {Component} from 'react';
import { Link, useHistory } from 'react-router-dom';
import {db} from '../server';
let tran = [];
componentDidMount(){
db.collection('transactions').orderBy('added_at', 'desc').onSnapshot(snapshot => {
let changes = snapshot.docChanges();
changes.forEach(change => {
if(change.type == 'added'){
tran.push(change.doc);
}
});
this.setState( {transactions: tran});
});
}
displayTransactions(){
return this.state.transactions.map(transaction => {
return <Transaction record={transaction.data()} key={transaction.id} sequence={transaction.id} />;
})
}
render(){
return(
<div className="container mt-4">
<h2>Transaction List</h2>
<div className="mt-5" id="renderTransactions">
{this.displayTransactions()}
</div>
</div>
)
}
import React,{Component}来自'React';
从“react router dom”导入{Link,useHistory};
从“../server”导入{db};
设tran=[];
componentDidMount(){
db.collection('transactions').orderBy('added_at','desc').onSnapshot(快照=>{
let changes=snapshot.docChanges();
changes.forEach(change=>{
如果(change.type=='added'){
交易推送(变更单);
}
});
this.setState({transactions:tran});
});
}
显示事务(){
返回此.state.transactions.map(事务=>{
返回;
})
}
render(){
返回(
交易清单
{this.displayTransactions()}
)
}
我的详细信息页面
componentDidMount(){
var docID = this.props.match.params.id;
db.collection('transactions').doc(docID).get().then( doc => {
let details = {
_id: doc.id,
title: doc.data().title,
details: doc.data().details,
category: doc.data().category,
dateTransaction: doc.data().dateTransaction,
amount: doc.data().amount,
transType: doc.data().transType,
}
this.setState( {transactionDetails: details});
});
}
transactionDetails(){
return <TransactionDetails record={this.state.transactionDetails} deleteTransaction={this.deleteTransaction} />;
}
render(){
return(
<div className="mt-5">
<div className="container">
<h2 className="mb-5">Transaction Details</h2>
{this.transactionDetails()}
</div>
</div>
)
}
componentDidMount(){
var docID=this.props.match.params.id;
db.collection('transactions').doc(docID).get().then(doc=>{
让详细信息={
_id:doc.id,
标题:doc.data().title,
详细信息:doc.data().details,
类别:doc.data().category,
dateTransaction:doc.data().dateTransaction,
金额:单据数据()金额,
transType:doc.data().transType,
}
this.setState({transactionDetails:details});
});
}
交易详情(){
返回;
}
render(){
返回(
交易详情
{this.transactionDetails()}
)
}
问题
好吧,看来你们是在间接地改变状态<代码>传输
缓存所有以前获取的数据库数据
let tran = [];
componentDidMount(){
db.collection('transactions').orderBy('added_at', 'desc').onSnapshot(snapshot => {
let changes = snapshot.docChanges();
changes.forEach(change => {
if(change.type == 'added'){
tran.push(change.doc);
}
});
this.setState({ transactions: tran });
});
}
tran
看起来是局部全局的,每次组件装载时,它都会将所有更改推送到tran
中,然后设置状态。每次安装组件时,它都会再次将所有更改推送到tran
并设置状态。这些后续装载使用现有填充的tran
数组,并可能推入重复数据
解决方案
我猜你是想让每一个坐骑都“新鲜”。为此,我建议将更改映射到您的状态。由于“将返回相同的数据元素,包括新添加的数据”,您可以简单地使用整个数组,因此无需将“状态”保持在组件之外,也无需按“添加的”元素进行过滤
componentDidMount(){
db.collection('transactions').orderBy('added_at', 'desc').onSnapshot(snapshot => {
const changes = snapshot.docChanges();
this.setState({ transactions: changes });
});
}
是否可以添加详细信息页面的渲染
功能映射数据并使用React键?请包括一个完整的例子。什么是tran
?在哪里申报?不管它是什么,你似乎都在变异。是的,你显然是在变异状态。你能澄清一下change.type=='added'
的作用吗?如果组件重新安装并且调用了相同的db查询,是否返回了不同的数据元素?@drewrese fthe change.type检查firebase数据库是否等于added,每次firebase中有新数据执行时,都会返回相同的数据元素,包括新添加的数据。