尝试将 setState 设置为带有对象的状态数组的特定索引时出错
Error when trying to setState to a specific index of a state array with objects
我正在尝试更改特定卡片组件 onPress 中 "show" 的状态。 onPress我过滤得到对象,把show的值设置为true。当我控制台记录更改的数组时,我可以看到更改但是当我设置状态时,我得到错误 "TypeError: Cannot read property 'show' of undefined"
我认为问题是当我初始化应用程序时,我从 "cards" 拼接(这样我就不会重复复制)并且 setState 呈现 CardBox 组件(并且 "cards" 是空),而不仅仅是卡片。谁能指出我解决这个问题的正确方向。
export default class CardBox extends React.Component {
constructor(props) {
super(props);
this.state = {
selected_cards: [],
rnd_card_list: [],
cards: [
{
id: 1,
name: "star",
color: "#ffeaa5",
show: false
},
{
id: 2,
name: "heart",
color: "#f3c1c6",
show: false
},
{
id: 3,
name: "headphones",
color: "#f58b54",
show: false
},
{
id: 4,
name: "bell-o",
color: "#107595",
show: false
},
{
id: 5,
name: "video-camera",
color: "#ff0b55",
show: false
},
{
id: 6,
name: "pencil",
color: "#a34a28",
show: false
},
{
id: 7,
name: "star",
color: "#ffeaa5",
show: false
},
{
id: 8,
name: "heart",
color: "#f3c1c6",
show: false
},
{
id: 9,
name: "headphones",
color: "#f58b54",
show: false
},
{
id: 10,
name: "bell-o",
color: "#107595",
show: false
},
{
id: 11,
name: "video-camera",
color: "#ff0b55",
show: false
},
{
id: 12,
name: "pencil",
color: "#a34a28",
show: false
}
]
};
}
handlePress = s_card => {
let rnd_list = this.state.rnd_card_list;
let x = rnd_list.indexOf(s_card);
var sCard = rnd_list.filter(card => card.id === s_card.id);
sCard[0].show = true;
rnd_list[x] = sCard[0];
this.setState({ rnd_list });
// if (this.state.selected_cards.length === 2) {
// if (
// this.state.selected_cards[0].name === this.state.selected_cards[1].name
// ) {
// alert("Same");
// } else {
// alert("Not Same");
// }
// this.state.selected_cards.pop();
// this.state.selected_cards.pop();
// }
};
shuffle = arr => {
for (var i = arr.length - 1; i > 0; i--) {
var j = Math.floor(Math.random() * (i + 1));
var temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
};
initGame = cards => {
let rndGrid = [];
for (var i = 0; i < 12; i++) {
var randomInd = Math.floor(Math.random() * Math.floor(cards.length - 1));
var card = cards[randomInd];
this.state.rnd_card_list.push(card);
cards.splice(randomInd, 1);
}
this.shuffle(this.state.rnd_card_list);
for (var i = 0; i < 12; i++) {
rndGrid.push(
<Card
key={i}
handlePress={this.handlePress}
card={this.state.rnd_card_list[i]}
/>
);
}
return rndGrid;
};
render() {
return (
<StyledCardContainer>
{this.initGame(this.state.cards)}
</StyledCardContainer>
);
}
}
-------------------------------------------------------
//card component
export default class Card extends React.Component {
render() {
let icon_name = "question";
let icon_color = "black";
if (this.props.card.show) {
icon_name = this.props.card.name;
icon_color = this.props.card.color;
}
return (
<TouchableOpacity onPress={() => this.props.handlePress(this.props.card)}>
<StyledCard>
<FontAwesome name={icon_name} size={40} color={icon_color} />
</StyledCard>
</TouchableOpacity>
);
}
}
你的代码中有一个小错误,具体在这里:
this.setState({ rnd_list });
你必须告诉 React 你想要更新哪一块状态,在这种情况下你想要更新 cards
的数组,否则 React 将用卡片数组重写所有内容
this.setState({ cards: rnd_list });
我正在尝试更改特定卡片组件 onPress 中 "show" 的状态。 onPress我过滤得到对象,把show的值设置为true。当我控制台记录更改的数组时,我可以看到更改但是当我设置状态时,我得到错误 "TypeError: Cannot read property 'show' of undefined"
我认为问题是当我初始化应用程序时,我从 "cards" 拼接(这样我就不会重复复制)并且 setState 呈现 CardBox 组件(并且 "cards" 是空),而不仅仅是卡片。谁能指出我解决这个问题的正确方向。
export default class CardBox extends React.Component {
constructor(props) {
super(props);
this.state = {
selected_cards: [],
rnd_card_list: [],
cards: [
{
id: 1,
name: "star",
color: "#ffeaa5",
show: false
},
{
id: 2,
name: "heart",
color: "#f3c1c6",
show: false
},
{
id: 3,
name: "headphones",
color: "#f58b54",
show: false
},
{
id: 4,
name: "bell-o",
color: "#107595",
show: false
},
{
id: 5,
name: "video-camera",
color: "#ff0b55",
show: false
},
{
id: 6,
name: "pencil",
color: "#a34a28",
show: false
},
{
id: 7,
name: "star",
color: "#ffeaa5",
show: false
},
{
id: 8,
name: "heart",
color: "#f3c1c6",
show: false
},
{
id: 9,
name: "headphones",
color: "#f58b54",
show: false
},
{
id: 10,
name: "bell-o",
color: "#107595",
show: false
},
{
id: 11,
name: "video-camera",
color: "#ff0b55",
show: false
},
{
id: 12,
name: "pencil",
color: "#a34a28",
show: false
}
]
};
}
handlePress = s_card => {
let rnd_list = this.state.rnd_card_list;
let x = rnd_list.indexOf(s_card);
var sCard = rnd_list.filter(card => card.id === s_card.id);
sCard[0].show = true;
rnd_list[x] = sCard[0];
this.setState({ rnd_list });
// if (this.state.selected_cards.length === 2) {
// if (
// this.state.selected_cards[0].name === this.state.selected_cards[1].name
// ) {
// alert("Same");
// } else {
// alert("Not Same");
// }
// this.state.selected_cards.pop();
// this.state.selected_cards.pop();
// }
};
shuffle = arr => {
for (var i = arr.length - 1; i > 0; i--) {
var j = Math.floor(Math.random() * (i + 1));
var temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
};
initGame = cards => {
let rndGrid = [];
for (var i = 0; i < 12; i++) {
var randomInd = Math.floor(Math.random() * Math.floor(cards.length - 1));
var card = cards[randomInd];
this.state.rnd_card_list.push(card);
cards.splice(randomInd, 1);
}
this.shuffle(this.state.rnd_card_list);
for (var i = 0; i < 12; i++) {
rndGrid.push(
<Card
key={i}
handlePress={this.handlePress}
card={this.state.rnd_card_list[i]}
/>
);
}
return rndGrid;
};
render() {
return (
<StyledCardContainer>
{this.initGame(this.state.cards)}
</StyledCardContainer>
);
}
}
-------------------------------------------------------
//card component
export default class Card extends React.Component {
render() {
let icon_name = "question";
let icon_color = "black";
if (this.props.card.show) {
icon_name = this.props.card.name;
icon_color = this.props.card.color;
}
return (
<TouchableOpacity onPress={() => this.props.handlePress(this.props.card)}>
<StyledCard>
<FontAwesome name={icon_name} size={40} color={icon_color} />
</StyledCard>
</TouchableOpacity>
);
}
}
你的代码中有一个小错误,具体在这里:
this.setState({ rnd_list });
你必须告诉 React 你想要更新哪一块状态,在这种情况下你想要更新 cards
的数组,否则 React 将用卡片数组重写所有内容
this.setState({ cards: rnd_list });