Я делаю игру в React и внедряю для нее таймер. Вот код для основного компонента игры: (потерпите меня, я, возможно, мог бы использовать циклы на некоторых элементах JSX и т. Д.)
import React, {Component} from 'react';
import './Game.css';
import ScoreBoard from '../ScoreBoard/ScoreBoard';
import cardBack from '../../Images/back.png';
import j from '../../Images/j.jpg'; import j2 from '../../Images/j2.png';
import j3 from '../../Images/j3.png'; import j4 from '../../Images/j4.png';
import q from '../../Images/q.jpg'; import q2 from '../../Images/q2.jpg';
import q3 from '../../Images/q3.png'; import q4 from '../../Images/q4.png';
import k from '../../Images/k.jpg'; import k2 from '../../Images/k2.jpg';
import k3 from '../../Images/k3.png'; import k4 from '../../Images/k4.jpg';
import a from '../../Images/a.png'; import a2 from '../../Images/a2.png';
import a3 from '../../Images/a3.png'; import a4 from '../../Images/a4.png';
let dealCards = true;
let arrayRandom = [];
let curCard1;
let curCard2;
let counter = 1;
let id1;
let id2;
let canClick = true;
let score = 0;
let tries = 0;
class Game extends Component {
state = {
card0: cardBack,
card1: cardBack,
card2: cardBack,
card3: cardBack,
card4: cardBack,
card5: cardBack,
card6: cardBack,
card7: cardBack,
card8: cardBack,
card9: cardBack,
card10: cardBack,
card11: cardBack,
card12: cardBack,
card13: cardBack,
card14: cardBack,
card15: cardBack,
card16: cardBack,
card17: cardBack,
card18: cardBack,
card19: cardBack,
card20: cardBack,
card21: cardBack,
card22: cardBack,
card23: cardBack,
card24: cardBack,
card25: cardBack,
card26: cardBack,
card27: cardBack,
card28: cardBack,
card29: cardBack,
card30: cardBack,
card31: cardBack,
timer: 0
}
selected = (event) => {
if (canClick === true) {
let id = event.currentTarget.id; //card0
let idString = id.toString(); //"card0"
//ONLY ALLOW A CARD TO BE CLICKED IF ITS FACE DOWN
if (this.state[idString] === cardBack) {
idString = idString.replace(/card/g, ''); //"0"
this.setState({[id] : arrayRandom[idString]});
//FIRST PICK
if (counter % 2 == 1) {
curCard1 = arrayRandom[idString].toString();
id1 = id;
counter++;
//SECOND PICK
} else {
//MAKE SURE A CARD DOESN'T GET SELECTED TWICE IN A ROW AND STAY FACE UP
if (id === id1) {
console.log("Select a different card for your second pick");
} else {
counter++;
tries++;
canClick = false; //STOP USER FROM SELECTING ANOTHER CARD
curCard2 = arrayRandom[idString].toString();
id2 = id;
setTimeout(() => {canClick = true}, 1000); //USER CAN PICK AGAIN IN 1 SEONCD
//IF THERE'S A MATCH - CARDS STAY FLIPPED, SCORE INCREASES BY 1
if (curCard1 == curCard2) {
score = score + 1;
//IF THERE'S NO MATCH - CARDS FLIP FACE DOWN AFTER A SECOND
} else {
setTimeout(() => {
this.setState({[id1]: cardBack});
this.setState({[id2]: cardBack});
}, 1000);
}
}
}
} else {
console.log("This card has already been flipped, select another one");
}
}
}
setInterval( () => { this.setState({timer: this.state.timer + 1}); }, 1000);
render() {
//SORT THE CARDS IF THEY HAVEN'T BEEN SORTED YET
if (dealCards === true) {
dealCards = false;
let arrayOrder = [j,j2,j3,j4,q,q2,q3,q4,k,k2,k3,k4,a,a2,a3,a4,j,j2,j3,j4,q,q2,q3,q4,k,k2,k3,k4,a,a2,a3,a4];
arrayRandom = arrayOrder.sort(sorter);
function sorter(a, b) {
return 0.5 - Math.random();
}
console.log(arrayRandom);
}
return (
<div id="gameBox">
<ScoreBoard score={score} timer={this.state.timer} tries={tries}/>
<img src={this.state.card0} id="card0" className="card" onClick={this.selected}/>
<img src={this.state.card1} id="card1" className="card" onClick={this.selected}/>
<img src={this.state.card2} id="card2" className="card" onClick={this.selected}/>
<img src={this.state.card3} id="card3" className="card" onClick={this.selected}/>
<img src={this.state.card4} id="card4" className="card" onClick={this.selected}/>
<img src={this.state.card5} id="card5" className="card" onClick={this.selected}/>
<img src={this.state.card6} id="card6" className="card" onClick={this.selected}/>
<img src={this.state.card7} id="card7" className="card" onClick={this.selected}/>
<img src={this.state.card8} id="card8" className="card" onClick={this.selected}/>
<img src={this.state.card9} id="card9" className="card" onClick={this.selected}/>
<img src={this.state.card10} id="card10" className="card" onClick={this.selected}/>
<img src={this.state.card11} id="card11" className="card" onClick={this.selected}/>
<img src={this.state.card12} id="card12" className="card" onClick={this.selected}/>
<img src={this.state.card13} id="card13" className="card" onClick={this.selected}/>
<img src={this.state.card14} id="card14" className="card" onClick={this.selected}/>
<img src={this.state.card15} id="card15" className="card" onClick={this.selected}/>
<img src={this.state.card16} id="card16" className="card" onClick={this.selected}/>
<img src={this.state.card17} id="card17" className="card" onClick={this.selected}/>
<img src={this.state.card18} id="card18" className="card" onClick={this.selected}/>
<img src={this.state.card19} id="card19" className="card" onClick={this.selected}/>
<img src={this.state.card20} id="card20" className="card" onClick={this.selected}/>
<img src={this.state.card21} id="card21" className="card" onClick={this.selected}/>
<img src={this.state.card22} id="card22" className="card" onClick={this.selected}/>
<img src={this.state.card23} id="card23" className="card" onClick={this.selected}/>
<img src={this.state.card24} id="card24" className="card" onClick={this.selected}/>
<img src={this.state.card25} id="card25" className="card" onClick={this.selected}/>
<img src={this.state.card26} id="card26" className="card" onClick={this.selected}/>
<img src={this.state.card27} id="card27" className="card" onClick={this.selected}/>
<img src={this.state.card28} id="card28" className="card" onClick={this.selected}/>
<img src={this.state.card29} id="card29" className="card" onClick={this.selected}/>
<img src={this.state.card30} id="card30" className="card" onClick={this.selected}/>
<img src={this.state.card31} id="card31" className="card" onClick={this.selected}/>
</div>
);
}
}
export default Game;
все работает, кроме моего таймера. эта строка является проблемой setInterval( () => { this.setState({timer: this.state.timer + 1}); }, 1000);
Я хочу, чтобы она добавляла одну в секунду и отображала время в реальном времени. Есть два способа сделать это из того, что я могу догадаться.
- глобальная переменная
let timer = 0;
, а затем сразу после, вне класса, под глобалами setInterval( () => { timer++; }, 1000);
. Я попробовал это, а затем просто использовал timer={timer}
как опору в компоненте табло. Это работает, но обновляется только тогда, когда что-то еще отображается. - состояние
timer: 0
. затем используйте setState, чтобы изменить его. проблема в том, что он начинает действовать очень странно, если я помещаю строку setInterval( () => { this.setState({timer: this.state.timer + 1}); }, 1000);
в метод рендеринга (как будто она постоянно повторяет рендеринг), и я не могу найти способ запустить ее вне метода рендеринга, как метод вкласс.
какие-нибудь идеи о том, как я могу заставить это время работать в моем компоненте React?