简体   繁体   English

出现错误:只能在 function 组件的主体内部调用挂钩

[英]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.

相关问题 错误:只能在函数组件的主体内部调用挂钩 - Error: Hooks can only be called inside the body of a function component Flyto 错误:只能在 function 组件的主体内部调用挂钩 - Flyto error: Hooks can only be called inside of the body of a function component 钩子只能在函数组件错误的主体内部调用 - Hooks can only be called inside the body of a function component error 未捕获错误:只能在函数组件的主体内部调用挂钩 - Uncaught Error: Hooks can only be called inside the body of a function component 获取错误 **错误:无效挂钩调用。 钩子只能在 function 组件的内部调用。 ** - Getting Error **Error: Invalid hook call. Hooks can only be called inside of the body of a function component. ** 反应,得到错误:无效的钩子调用。 Hooks 只能在函数组件的主体内部调用 - React, getting Error: Invalid hook call. Hooks can only be called inside of the body of a function component 获取**错误:无效的挂钩调用。 钩子只能在 function 组件的主体内部调用。 ** - Getting **Error: Invalid hook call. Hooks can only be called inside of the body of a function component. ** 挂钩的调用在功能组件内部给出错误挂钩只能在 function 组件的主体内部调用 - Call of hooks is inside of functional component give error Hooks can only be called inside of the body of a function component 收到此错误“无效的挂钩调用。 钩子只能在 function 组件的主体内部调用。” 在反应功能组件内? - Getting this error “Invalid hook call. Hooks can only be called inside of the body of a function component.” inside a react functional component? 在 HOC 中使用 useState/Hooks 导致错误“Hooks can only be called inside of a function component” - React Using useState/Hooks In HOC Causes Error "Hooks can only be called inside of the body of a function component"
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM