[英]getting error : Hooks can only be called inside of the body of a function component
i am working on setInterval
functionality for that i have used, React.useRef
, but when i run the page i am getting this error.我正在为我使用过的
setInterval
功能React.useRef
,但是当我运行该页面时,我收到了这个错误。 Hooks can only be called inside of the body of a function component.
, here i have uploaded my whole code, can anyone please help me why i am getting this error? ,在这里我已经上传了我的整个代码,任何人都可以帮助我为什么会出现这个错误? any help will be really appreciated, thanks
任何帮助将不胜感激,谢谢
import * as React from "react";
import * as ReactDOM from "react-dom";
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 = '30:00';
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.useRef<any>();
}
public componentDidMount(): void
{
GameDataStore.listen(data => this.setState({
gameData: data
}));
UserDataStore.listen(data => this.setState({
userData: data
}));
}
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 = localStorage.getItem('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(minutes + ":" + seconds);
_self.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 startTimer = () => {
localStorage.setItem('is_called','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)
{
clearInterval(this.interval_counter.current);
localStorage.setItem('is_started','1');
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);
//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 gameData.game.id !== undefined && gameData.game.id!=null) {
localStorage.setItem('game_id',gameData.game.id);
}
if(typeof gameData.game.chooserGuid !== undefined && gameData.game.chooserGuid!=null) {
localStorage.setItem('chooserGuid',gameData.game.chooserGuid);
}
let is_called = localStorage.getItem('is_called');
if(is_called == "0") {
this.startTimer();
}
}
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}
/>
</>
);
}
}
The problem is that you are using a React hook inside a class component.问题是您在 class 组件中使用了 React 钩子。
Hooks can only be used inside function components, which means your usage of the useRef
hook inside the GamePlayBlack
constructor is illegal.钩子只能在 function 组件内部使用,这意味着您在
GamePlayBlack
构造函数中使用useRef
钩子是非法的。
Instead, use the React.createRef()
method:相反,使用
React.createRef()
方法:
this.interval_counter = React.createRef<any>();
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.