【发布时间】:2021-09-17 15:39:44
【问题描述】:
我正在尝试构建一个应用程序,用户可以在其中将一张卡片添加到一组卡片中,然后将特定卡片的位置与卡片向左或向右切换。我写了一个函数,我相信它会用左侧的卡片切换卡片,但我正在努力调试它,因为所选卡片的索引似乎没有正确传递给子组件。 到目前为止,这是我的代码:
CardList.js 是试图将 moveLeft 方法传递给 cardItem
import React from "react";
import CardItem from "./CardItem";
import CardForm from "./CardForm";
import './Card.css';
class CardList extends React.Component {
state = {
cards: JSON.parse(localStorage.getItem(`cards`)) || []
// when the component mounts, read from localStorage and set/initialize the state
};
componentDidUpdate(prevProps, prevState) { // persist state changes to longer term storage when it's updated
localStorage.setItem(
`cards`,
JSON.stringify(this.state.cards)
);
}
render() {
const cards = this.getCards();
const cardNodes = (
<div style={{ display: 'flex' }}>{cards}</div>
);
return (
<div>
<CardForm addCard={this.addCard.bind(this)} />
<div className="container">
<div className="card-collection">
{cardNodes}
</div>
</div>
</div>
);
}
addCard(name) {
const card = {
name
};
this.setState({
cards: this.state.cards.concat([card])
}); // new array references help React stay fast, so concat works better than push here.
}
removeCard(index) {
this.state.cards.splice(index, 1)
this.setState({
cards: this.state.cards.filter(i => i !== index)
})
}
moveLeft(index, card) {
this.setState((prevState, prevProps) => {
return {cards: prevState.cards.map(( c, i)=> {
// also handle case when index == 0
if (i === index) {
return prevState.cards[index - 1];
} else if (i === index - 1) {
return prevState.cards[index];
}
})};
});
}
//moveRight(index, card) {
// ?
// }
getCards() {
return this.state.cards.map((card) => {
return (
<CardItem
card={card}
index={card.index}
name={card.name}
removeCard={this.removeCard.bind(this)}
moveLeft={this.moveLeft.bind(this)}
// moveRight={this.moveRight}
/>
);
});
}
}
export default CardList;
cardItem 正在努力寻找必要卡片的索引,即使我将它作为道具传递。我收到一条错误消息“×
TypeError: Cannot read property 'index' of undefined" 源自我的 CardList 组件。
import React from 'react';
import Card from "react-bootstrap/Card";
import Button from "react-bootstrap/Button";
class CardItem extends React.Component {
render() {
return (
<div>
<Card style={{ width: '15rem'}}>
<Card.Header as="h5">{this.props.name}</Card.Header>
<Card.Body>
<Button variant="primary" onClick={this.handleClick.bind(this)}>Remove</Button>
</Card.Body>
<Card.Footer style={{ display: 'flex' }}>
<i class="arrow left icon" onClick={this.leftClick.bind(this)} style={{ color: 'blue'}}></i>
{/*<i class="arrow right icon" onClick={rightClick(index, card)} style={{ color: 'blue'}}></i>*/}
</Card.Footer>
</Card>
</div>
)
}
handleClick(index) {
this.props.removeCard(index)
}
leftClick(index, card) {
this.props.moveLeft(index,card)
}
rightClick(index, card) {
this.props.moveRight(index, card)
}
}
export default CardItem;
我怎样才能最好地将必要的索引作为道具传递下去?谢谢
编辑#1 我在 addCard 方法中犯了一个错误,我从未将索引分配给卡片。我已经解决了这个问题,并在我的地图返回函数中添加了一个关键属性,但现在我收到一条错误消息“× TypeError:无法读取未定义的属性“名称” 请参阅下面更新的 CardList.js:
import React from "react";
import CardItem from "./CardItem";
import CardForm from "./CardForm";
import './Card.css';
class CardList extends React.Component {
state = {
cards: JSON.parse(localStorage.getItem(`cards`)) || []
// when the component mounts, read from localStorage and set/initialize the state
};
componentDidUpdate(prevProps, prevState) { // persist state changes to longer term storage when it's updated
localStorage.setItem(
`cards`,
JSON.stringify(this.state.cards)
);
}
render() {
const cards = this.getCards();
const cardNodes = (
<div style={{ display: 'flex' }}>{cards}</div>
);
return (
<div>
<CardForm addCard={this.addCard.bind(this)} />
<div className="container">
<div className="card-collection">
{cardNodes}
</div>
</div>
</div>
);
}
addCard(name, index) {
const card = {
name,
index
};
this.setState({
cards: this.state.cards.concat([card])
}); // new array references help React stay fast, so concat works better than push here.
}
removeCard(index) {
this.state.cards.splice(index, 1)
this.setState({
cards: this.state.cards.filter(i => i !== index)
})
}
moveLeft(index, card) {
this.setState((prevState, prevProps) => {
return {cards: prevState.cards.map(( c, i)=> {
// also handle case when index == 0
if (i === index) {
return prevState.cards[index - 1];
} else if (i === index - 1) {
return prevState.cards[index];
}
})};
});
}
//moveRight(index, card) {
// ?
// }
getCards() {
return this.state.cards.map((card) => {
return (
<CardItem
card={card}
key={card.index}
name={card.name}
removeCard={this.removeCard.bind(this)}
moveLeft={this.moveLeft.bind(this)}
// moveRight={this.moveRight}
/>
);
});
}
}
export default CardList;
【问题讨论】:
-
我看不到你在哪里设置你的
card.index。在您的addCard函数中,您只传递了name,并且您没有在返回map函数时设置key。 -
谢谢,我做了这些更改,但现在我收到了一个不同的错误,如我上面的编辑中所述
-
您确定您的
concat功能正常工作吗?试试push看看是否可行。 -
当我将其更改为推送然后尝试添加新卡时,我得到一个不同的错误,说'TypeError:this.state.cards.map is not a function'
-
你需要注意几个不同的snafu,比如
removeCard(index) { this.state.cards.splice(index, 1),这里你是直接变异状态,这是一个大问题。必须继续前进一段时间,但我猜你正在覆盖你的卡状态,你应该使用调试器或一些 console.logs 来跟踪你的卡状态到底在做什么。
标签: javascript arrays reactjs parent-child react-props