javascript - 单击左箭头或右箭头以切换数组中的元素与左侧或右侧的元素 React
问题描述
我是 React 的新手,正在尝试构建一个应用程序,用户可以在其中创建卡片、删除卡片,并通过单击向左或向右箭头来更改卡片数组的顺序,以使用左侧或左侧的元素切换元素正确的。我正在努力编写这个功能。我已经编写了将卡与左侧的卡进行切换的功能,但是该功能现在没有做任何事情。我也没有从这个函数的控制台中得到任何错误,所以我真的无法确定我哪里出错了。这是到目前为止的代码:
CardList.js 将显示添加卡片的表单并显示 CardItems 数组,传递函数以将这些项目向左或向右切换('moveLeft','moveRight')作为道具。
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) {
if (index > 1) {
this.state.cards.splice(index, 1);
this.state.cards.splice((index !== 0) ? index - 1 : this.state.cards.length, 0, card)
}
return this.state.cards
}
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.bind(this)}
/>
);
});
}
}
export default CardList;
CardItem 正在接受这些道具,并在单击左或右图标后理想地处理在数组中向左或向右移动卡片。
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={this.rightClick.bind(this)} 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 嘿伙计们,所以我写了一个不同的函数来处理将卡片向左移动,我决定在构造函数中将“this”绑定到该方法,因为我收到错误说程序无法读取它。但是,我仍然收到错误,基本上说当我将函数从 CardList 传递给 CardItem 作为道具时,一切都没有定义。有谁知道问题是什么?当我调用 CardItem 中的方法时,我怀疑它是我的语法。
CardList.js
import React from "react";
import CardItem from "./CardItem";
import CardForm from "./CardForm";
import './Card.css';
class CardList extends React.Component {
constructor(props) {
super();
this.moveLeft = this.moveLeft.bind(this);
this.moveRight = this.moveRight.bind(this);
this.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}
moveRight={this.moveRight}
/>
);
});
}
}
export default CardList;
CardItem.js
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={leftClick(index, card)} 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;
解决方案
要在 React 中更新状态数组,你不应该使用splice
,push
或[]
操作符。
而是使用返回新数组对象的方法,即。map
, filter
, concat
, slice
.
有关详细说明,请参阅本文。
因此,您可以执行以下操作:
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];
}
})};
});
}
当使用之前的值更新 React 状态时,总是使用
setState((prevState,prevProps)=>{ return ...})
因此,状态更新可能是异步的。请参阅 React 文档。
由于您是从子组件调用父组件方法,因此最好在CardList
构造函数中绑定这些方法。例如:
this.moveLeft = this.moveLeft.bind(this);
this.moveRight ....
推荐阅读
- c# - 如何动态创建视图 MVC
- java - Apache POI - 如何获取与 Excel 中显示的格式完全相同的日期?
- bash - 如何编写 for 循环以将数据提取到新创建的文件?
- java - 使用子类对象的继承方法返回父类变量
- javascript - 开玩笑 getReversedNavigationSections of null
- php - 为什么 curl 抛出异常,错误 35
- ios - 如何在 Corespotlight 搜索中显示消息和视频按钮?
- jquery - 如何将剑道网格层次结构的两个孩子放入选项卡?
- html - 将 Twitter 提要嵌入网站,但显示在轮播中
- python - 从 Quantlib BachelierSwaption 价格中检索 Black vol