我是React的新手,并开始从事记忆游戏,您可以翻牌并比较两张牌。我无法理解如何更改单个组件的状态。现在,当我单击某个组件时,所有组件的状态都会更改,并且我所有的卡都变成红色而不是一个。后来我想添加照片,但现在仅测试背景色。我也知道我必须添加一些逻辑/功能,但是无法解决过去的状态问题。
App.js
import React, {Component} from 'react';
import './App.css';
import Grid from './grid/grid';
import Header from './Header/header';
import Footer from './Footer/footer';
class App extends Component {
cards = [{id:1, name: 'dog'},{id:2, name: 'dog'},{id:3, name: 'cat'},{id:4, name: 'cat'},{id:5, name: 'mouse'},{id:6, name: 'mouse'},{id:7, name: 'horse'},{id:8, name: 'horse'},
{id:9, name: 'pig'},{id:10, name: 'pig'},{id:11, name: 'chicken'},{id:12, name: 'chicken'},{id:13, name: 'cow'},{id:14, name: 'cow'},{id:15, name: 'fox'},{id:16, name: 'fox'}]
.sort( () => Math.random() - 0.5);
clicks = [];
state = {
current: 0,
}
clickHandler = (click) => {
this.clicks.push(click.name);
this.setState({
current: 1
})
console.log(this.clicks);
if (this.clicks.length > 1) {
this.compare(click.name);
}
}
compare = (name) => {
if (name === this.clicks[0]) {
console.log('pair')
} else {
console.log('nope');
}
}
render() {
return (
<div className="App">
<Header />
<div className='Grid-container'>
<div className='wrapper'>
{this.cards.map(child =>
<Grid click={() => this.clickHandler(child)}
active={this.state.current === 0}
id={child.id}
/>)}
</div>
</div>
<Footer />
</div>
);
}
}
export default App;
grid.js
import React from 'react';
import './grid.css';
const Grid = (props) => {
return (
<div className={'Child' + (props.active ? '': ' active')}
onClick={props.click}
>
{props.id}
</div>
);
}
export default Grid;
App.css
.Grid-container {
display: flex;
background-color: black;
justify-content: center;
align-items: center;
}
.wrapper {
display: grid;
width: 700px;
grid-template-columns: repeat(4, 1fr);
grid-template-rows: repeat(4, 1fr);
grid-gap: 10px;
background-color: black;
justify-content: center;
align-items: center;
}
**grid.css**
.Child {
width: auto;
height: 120px;
background-color: azure;
border-radius: 10px;
}
.Child.active {
width: auto;
height: 120px;
background-color: red;
border-radius: 10px;
}
答案 0 :(得分:0)
您必须为此使用index
。您在index
中将map
作为第二个参数,
{this.cards.map( ( child, index ) =>
<Grid
click={() => this.clickHandler(child,index)}
active={this.state.current === index}
id={child.id}
key ={child.id} //Provide unique key here
/>
)}
您的点击应为
clickHandler = (click,index) => {
this.clicks.push(click.name);
this.setState({
current: index //Set index in a state
})
console.log(this.clicks);
if (this.clicks.length > 1) {
this.compare(click.name);
}
}
您需要将current
状态初始化为空,否则默认情况下您将获得第一个网格激活
state = {
current: '',
}
您的Grid
组件就是这个,
const Grid = (props) => {
return (
<div
className={`Child ${props.active ? 'active': ''}`} //Your condition should be this
onClick={props.click}
>
{props.id}
</div>
);
}
答案 1 :(得分:0)
更新状态部分
state = {
current: -1, // nothing is selected it contains id of selected card
clicks: [],
}
clickHandler = (selectedId) => {
const { clicks, current } = this.state;
if (current === -1) { // no card selected to check
this.setState({
current: selectedId,
clicks: clicks.includes(selectedId) ? clicks : [...clicks, selectedId],
});
return; // no more in this funtion
}
if (selectedId === current) { // already selected card(totally same card)
this.setState({
current: -1, // unselect last selected card :(
clicks: clicks.slice(0, clicks.length - 1), // remove last selected click
});
} else { // different card. here check if they have same name
if (this.cards[selectedId].name === this.cards[current].name) {
// couple cards
console.log('Bingo They are Same!!!');
this.setState({
current: -1,
clicks: [...cliks, selectedId], // add just selected card in cliks
});
} else {
// Oh, you failed!
this.setState({
current: -1, // unselect last selected card :(
clicks: clicks.slice(0, clicks.length - 1),
});
}
}
}
渲染
...
<Grid
click={() => this.clickHandler(child.id)}
active={this.state.clicks.includes(child.id)} // check if it is included in clicks
id={child.id}
/>
...
这时您可以看到很酷的纸牌游戏。 :)