【发布时间】:2018-06-11 14:49:33
【问题描述】:
我正在通过创建应用程序来学习反应,但我的代码中有一个奇怪的问题,有人可以指出错误吗?谢谢
test=()=>{
console.log('filtered card: ',this.state.cards.filter(c=>c.id===this.state.idToDelete)[0].name)
}
当我使用此函数测试代码行时,它可以正常工作,并且在我单击时正确显示所有名称,但是当我应用该行进行渲染时,我可以将名称放入我的 Jsx 中给我错误?
const warningCard=this.state.idToDelete && this.state.cards.filter(c=>c.id===this.state.idToDelete)[0].name.toUpperCase()
return(
<div>
<button onClick={this.test}>test</button>
<button onClick={()=>this.setState({showForm:!this.state.showForm})}>form</button>
<button onClick={()=>this.setState({showEditForm:false})}>close edit from</button>
<h2>you have {this.state.cards.length} {card}</h2>
{this.state.showWarning &&
<div>
<h2>ARE YOU SURE YOU WANT TO DELETE THIS {warningCard} CARD?</h2>
这是图片
当我使用 console.log 并注释掉 warningCard 时,所有卡片都正确显示了它们的名称,但是当我在其中添加 warningCard 行时出现此错误
如果有帮助,这是我的完整组件
import React from 'react';
import CardList from './cardList';
import CardForm from './cardForm';
class FlashCardMainPage extends React.Component{
constructor(){
super();
this.state={
cards:[
{...},
{...},
{...}],
nextId:3,
showForm:false,
showEditForm:false,
cardToEdit:{},
showWarning:false,
confirm:false,
idToDelete:''
}
}
onCardClick=(id)=>{
const {cards}=this.state
const newCardsState=this.state.cards.map((c)=> c.id===id ? {...c,showInfo:!c.showInfo} : c)
this.setState({cards:newCardsState})
}
deleteCard=(id)=>{
this.setState({showWarning:true})
this.setState({idToDelete:id})
}
editCard=(id)=>{
const cardToEdit = this.state.cards.filter(c=>c.id===id)
this.setState({cardToEdit, showEditForm:true})
}
onFormSubmit=(cardFromSubmit)=>{
const newCard={id:this.state.nextId,...cardFromSubmit}
this.setState({
cards:[...this.state.cards,newCard],
nextId:this.state.nextId+1,
cardToEdit:{},
showForm:false
})
}
onEditCardSubmit=(editedCard)=>{
this.setState({showEditForm:false})
const cards=this.state.cards.map((c)=>c.id===this.state.cardToEdit[0].id?c={id:c.id,...editedCard}:c)
this.setState({cards})
}
onCloseForm=()=>{
this.setState({showForm:false, showEditForm:false})
}
test=()=>{
console.log('filtered card: ',this.state.cards.filter(c=>c.id===this.state.idToDelete)[0].name)
}
onConfirm=(pass)=>{
const check=pass
if(pass){
const cards=this.state.cards.filter(c=>c.id!==this.state.idToDelete)
this.setState({cards, showWarning:false})
}else
this.setState({showWarning:false})
}
render(){
const card=this.state.cards.length===1?'card':'cards'
const filteredCards = this.state.idToDelete && this.state.cards.filter(c=>c.id===this.state.idToDelete);
const warningCard = filteredCards[0] && filteredCards[0].name.toUpperCase();
return(
<div>
<button onClick={this.test}>test</button>
<button onClick={()=>this.setState({showForm:!this.state.showForm})}>form</button>
<button onClick={()=>this.setState({showEditForm:false})}>close edit from</button>
<h2>you have {this.state.cards.length} {card}</h2>
{this.state.showWarning &&
<div>
<h2>ARE YOU SURE YOU WANT TO DELETE THIS {warningCard} CARD?</h2>
<button onClick={()=>this.onConfirm(true)}>Yes</button>
<button onClick={()=>this.onConfirm(false)}>No</button>
</div>
}
{this.state.showForm &&
<CardForm
cardSave={this.onFormSubmit}
closeForm={this.onCloseForm}
/>
}
{this.state.showEditForm &&
<CardForm
editCardSave={this.onEditCardSubmit}
cardToEdit={this.state.cardToEdit}
closeForm={this.onCloseForm}
editStatus={this.state.showEditForm}
/>
}
<CardList
cards={this.state.cards}
cardClick={this.onCardClick}
deleteCard={this.deleteCard}
editCard={this.editCard}
/>
</div>
)
}
}
export default FlashCardMainPage
【问题讨论】:
-
这是一个非常不安全的操作
this.state.cards.filter(c=>c.id===this.state.idToDelete)[0],因为你怎么知道filter的结果不会为空呢?所以由于某种原因它是空的 -
如果您可以在此处创建代码的工作示例,那么解决问题会容易得多...codesandbox.io
-
到目前为止,我的应用运行良好。所有卡片都已正确更新和编辑。我只有一个看似简单的问题,但它让我非常头疼。我认为过滤器不会给我一个空数组,因为道具是从数组本身的卡片传递的。