我使用了setInterval
,并以此为基础显示计时器,但是setState
不适用于该功能
this.setState({
updateTimer: minutes + ":" + seconds
});
在componentDidMount()
中,我正在调用this.startTimer();
函数,但是此函数不会更新setState
,这里我已经上传了我的完整代码,有人可以检查我的代码并为我提供帮助解决此问题?
import * as React from "react";
import {GameDataStore, GameDataStorePayload} from "../../Global/DataStore/GameDataStore";
import {UserData, UserDataStore} from "../../Global/DataStore/UserDataStore";
import Grid from "@material-ui/core/Grid";
import {BlackCard} from "../../UI/BlackCard";
import Divider from "@material-ui/core/Divider";
import {Typography} from "@material-ui/core";
import {RevealWhites} from "./Components/Gameplay/RevealWhites";
import {ShowWinner} from "./Components/Gameplay/ShowWinner";
import {PickWinner} from "./Components/Gameplay/PickWinner";
import {LoadingButton} from "../../UI/LoadingButton";
import {PlayersRemaining} from "./Components/Gameplay/PlayersRemaining";
import {CardPlayTimeRemaining} from "./Components/Gameplay/CardPlayTimeRemaining";
import {ContainerProgress} from "../../UI/ContainerProgress";
import {cardDefsLoaded} from "../../Global/Utils/GameUtils";
import { id } from "apicache";
interface IGamePlayBlackProps
{
}
interface DefaultProps
{
}
type Props = IGamePlayBlackProps & DefaultProps;
type State = IGamePlayBlackState;
interface IGamePlayBlackState
{
gameData: GameDataStorePayload;
userData: UserData;
buttonLoading: boolean;
gameStarted: boolean;
updateTimer : string;
clearintervaltimer : string;
is_started : string;
intervalId : any;
}
export class GamePlayBlack extends React.Component<Props, State>
{
public setTimer = '00:30';
public setSeconds = 30;
public interval_counter;
constructor(props: Props)
{
super(props);
this.state = {
gameData: GameDataStore.state,
userData: UserDataStore.state,
buttonLoading: false,
gameStarted: false,
updateTimer: this.setTimer,
clearintervaltimer : '',
is_started : '0',
intervalId : Function(),
};
localStorage.setItem('is_called','0');
localStorage.setItem('is_called_show_winner_card','0');
this.interval_counter = React.createRef<any>();
}
public componentDidMount(): void
{
GameDataStore.listen(data => this.setState({
gameData: data
}));
UserDataStore.listen(data => this.setState({
userData: data
}));
const me = this.state.gameData.game?.players?.[this.state.userData.playerGuid];
const defsLoaded = cardDefsLoaded(this.state.gameData);
if (!me || !this.state.gameData.game || !defsLoaded)
{
clearInterval(this.interval_counter.current);
} else {
let game_id = this.state.gameData.game.id;
let chooserGuid = this.state.gameData.game.chooserGuid;
let all_players = this.state.gameData.game.players;
let all_player_id = Object.keys(all_players);
//alert(gameData.game.chooserGuid);
let filteredAry = all_player_id.filter(e => e !== this.state.userData.playerGuid);
//let filteredAry = all_player_id[0];
console.log("user player guid:"+this.state.userData.playerGuid);
console.log("guid:"+chooserGuid);
console.log("all players:"+all_player_id);
console.log("new array:"+filteredAry);
let target_item = filteredAry.find((_, i, ar) => Math.random() < 1 / (ar.length - i));
if(typeof target_item !== undefined && target_item!=null) {
localStorage.setItem('target_turn',target_item);
}
localStorage.setItem('is_started','0');
if(typeof this.state.gameData.game.id !== undefined && this.state.gameData.game.id!=null) {
localStorage.setItem('game_id',this.state.gameData.game.id);
}
if(typeof this.state.gameData.game.chooserGuid !== undefined && this.state.gameData.game.chooserGuid!=null) {
localStorage.setItem('chooserGuid',this.state.gameData.game.chooserGuid);
}
let is_called = localStorage.getItem('is_called');
if(is_called == "0") {
this.startTimer();
}
}
}
private onSelect = (winningPlayerGuid: string) =>
{
return GameDataStore.chooseWinner(this.state.userData.playerGuid, winningPlayerGuid);
};
private onClickStartRound = () =>
{
localStorage.setItem('is_started','1');
clearInterval(this.interval_counter.current);
this.setState({
buttonLoading: true,
gameStarted: true,
});
GameDataStore.startRound(this.state.userData.playerGuid)
.finally(() => this.setState({
buttonLoading: false,
gameStarted: true,
}));
};
private onClickSkipBlack = () =>
{
this.setState({
buttonLoading: true
});
GameDataStore.skipBlack(this.state.userData.playerGuid)
.finally(() => this.setState({
buttonLoading: false
}));
};
private skipPlayer = (game_string_id:any,target_turn:any,chooserGuid:any) => {
return GameDataStore.skipPlayer(game_string_id,target_turn,chooserGuid);
}
public interval = () => {
let timer = this.setSeconds, minutes, seconds;
let _self = this;
let is_started = this.state.is_started;
if(is_started == "0") {
let chooserGuid = localStorage.getItem('chooserGuid');
let game_string_id = localStorage.getItem('game_id');
let target_turn = localStorage.getItem('target_turn');
let is_called = localStorage.getItem('is_called');
if(typeof timer!==undefined && timer!=null) {
minutes = parseInt(timer/60 as any,10);
seconds = parseInt(timer%60 as any,10);
minutes = minutes < 10 ? "0" + minutes : minutes;
seconds = seconds < 10 ? "0" + seconds : seconds;
console.log("test");
console.log(minutes + ":" + seconds);
this.setState({
updateTimer: minutes + ":" + seconds
});
if(timer == 0) {
//alert("start next round");
_self.skipPlayer(game_string_id,target_turn,chooserGuid);
clearInterval(this.interval_counter.current);
}
if (--timer < 0) {
//alert(timer);
clearInterval(this.interval_counter.current);
}
this.setSeconds-=1;
}
}
}
public clearTimer = () => {
this.setState({is_started:'0'});
}
public startTimer = () => {
this.setState({is_started:'1'});
console.log("called again");
this.interval_counter.current = setInterval(this.interval, 1000);
}
public render()
{
const {
gameData,
buttonLoading
} = this.state;
const me = gameData.game?.players?.[this.state.userData.playerGuid];
const defsLoaded = cardDefsLoaded(gameData);
if (!me || !gameData.game || !defsLoaded)
{
return <ContainerProgress />;
} else {
let game_id = gameData.game.id;
let chooserGuid = gameData.game.chooserGuid;
let all_players = gameData.game.players;
let all_player_id = Object.keys(all_players);
}
const {
players,
chooserGuid,
roundCards,
roundStarted,
} = gameData.game;
const roundCardKeys = Object.keys(roundCards ?? {});
const remainingPlayerGuids = Object.keys(players ?? {})
.filter(pg => !(pg in (roundCards ?? {})) && pg !== chooserGuid);
const remainingPlayers = remainingPlayerGuids.map(pg => unescape(players?.[pg]?.nickname));
const revealedIndex = this.state.gameData.game?.revealIndex ?? 0;
const timeToPick = remainingPlayers.length === 0;
const revealMode = timeToPick && revealedIndex < roundCardKeys.length;
const hasWinner = !!gameData.game?.lastWinner;
return (
<>
<div>
<PlayersRemaining/>
</div>
<Divider style={{margin: "1rem 0"}}/>
{!roundStarted && (
<Typography style={{marginBottom: "1rem", textAlign: "center"}}>
<strong>You are the Card Captain!</strong>
<br/>
Read the card aloud, then click Start The Round. Once everyone plays, you will choose your favorite!<br/>
<span> {this.state.updateTimer}</span> Seconds
</Typography>
)}
{!timeToPick && roundStarted && (
<CardPlayTimeRemaining gameData={gameData}/>
)}
<Grid container spacing={2} style={{justifyContent: "center", marginTop: "1rem"}}>
{(!hasWinner) && (
<Grid item xs={12} sm={6} md={4} lg={3}>
<BlackCard packId={gameData.game?.blackCard.packId}>
{gameData.blackCardDef?.content}
</BlackCard>
</Grid>
)}
<RevealWhites canReveal={true}/>
<ShowWinner/>
</Grid>
{!roundStarted && (
<div style={{marginTop: "1rem", textAlign: "center"}}>
<LoadingButton loading={buttonLoading} color={"secondary"} variant={"outlined"} onClick={this.onClickSkipBlack}>
Skip Card
</LoadingButton>
<LoadingButton loading={buttonLoading} color={"secondary"} variant={"contained"} onClick={this.onClickStartRound} style={{marginLeft: "1rem"}}>
Start the round!
</LoadingButton>
</div>
)}
<PickWinner
canPick={true}
hasWinner={hasWinner}
onPickWinner={this.onSelect}
revealMode={revealMode}
timeToPick={timeToPick}
/>
</>
);
}
}