You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ReactJS/NextJS中useState触发标签页崩溃问题求助

问题分析与解决方案

核心问题

标签页冻结+路由报错的根源有两点:

  1. 组件每次渲染都会重复绑定auth.onAuthStateChanged监听,状态更新触发重新渲染后又会再次绑定监听,形成无限循环,最终导致页面冻结。
  2. router.push在服务器端渲染(SSR)阶段被调用,此时Next.js的router实例尚未初始化,触发"No router instance found"错误。

解决方案

步骤1:用useEffect包裹auth监听,避免重复绑定

将auth状态监听逻辑放到useEffect中,设置空依赖数组确保仅在组件挂载时绑定一次,同时添加清理函数避免内存泄漏:

import {useRouter} from "next/router";
import React, {useState, useEffect} from "react";
import {BsArrowDownCircle} from "react-icons/bs";
import {auth} from "./../../firebase";
import { ToastContainer, toast } from 'react-toastify';
import 'react-toastify/dist/ReactToastify.css';

export default function uploadFiles() {
    const router = useRouter();
    const [loggedIn, setLoggedIn] = useState(false);
    const [openAddFolders, setOpenAddFolders] = useState(false);

    useEffect(() => {
        // 绑定auth状态监听
        const unsubscribe = auth.onAuthStateChanged(function(user) {
            if (user) {
                setLoggedIn(true);
            }else{
                toast.error("Please Sign In, You Are Being Redirected");
                setTimeout(function(){
                    // 仅在客户端执行路由跳转
                    if (typeof window !== 'undefined') {
                        router.push("/");
                    }
                }, 5000);
            }
        });

        // 组件卸载时移除监听
        return unsubscribe;
    }, [router, toast]);

    function openAddFoldersMenu()
    {
        setOpenAddFolders(true);
    }

    function openUploadImagesMenu()
    {
        console.log("b");
    }

    return(
        <React.Fragment>
            <ToastContainer />
            {loggedIn ?
                <div className="flex items-center justify-center">
                    <div className="w-1/2">
                        <div onClick={openAddFoldersMenu} className="hover:cursor-pointer my-10 rounded-t-3xl w-full p-9 hover:bg-cyan-400 hover:text-white hover:shadow-cyan-500/50 shadow-lg ease-linear duration-100">
                            <div className="flex justify-between">
                                <h1>Add Folders</h1>
                                <BsArrowDownCircle className="animate-bounce" size={20} />
                            </div>
                            {/* <div className={addFolders ? "" : "hidden"}>
                                Some Information
                                
                            </div> */}
                        </div>

                        <div onClick={() => openUploadImagesMenu()} className="hover:cursor-pointer rounded-t-3xl w-full p-9 hover:bg-cyan-400 hover:text-white hover:shadow-cyan-500/50 shadow-lg ease-linear duration-100">
                            <div className="flex justify-between">
                            <h1>Upload Images</h1>
                                <BsArrowDownCircle className="animate-bounce" size={20} />
                            </div>
                            <div className="hidden">
                                Some Information
                            </div>
                        </div>
                    </div>
                </div>
            :
            <div className="w-[100vw] h-[100vh] bg-red-500 flex items-center justify-center">
                <h1 className="text-gray-50 text-7xl text-center">There Was A Problem Loading, <br /> Please Sign In</h1>
            </div>
            }
        </React.Fragment>
        
    );
};

步骤2:确保路由跳转仅在客户端执行

在router.push前添加typeof window !== 'undefined'判断,避免在服务器端调用客户端路由方法,彻底解决"No router instance found"错误。


修改后,auth监听只会绑定一次,不会引发无限循环;路由跳转仅在客户端执行,setOpenAddFolders(true)也能正常触发状态更新,页面冻结问题即可解决。

内容的提问来源于stack exchange,提问作者user19474938

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.25 22:24:30