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

NextJS 13迁移时出现Context used outside of provider错误求助

解决Next.js 13 App目录下Context使用报错「context used outside of provider.」

问题根源

  1. App目录组件默认是服务器组件:你的login路由页面如果未标记'use client',会以服务器组件形式渲染,而服务器组件无法调用useContext等客户端hooks,直接调用会触发错误。
  2. AuthContext初始值为undefined且未处理加载状态:Provider中auth初始为undefined,且通过useEffect异步初始化,组件首次渲染(尤其是服务器端渲染)时,useAuthContext会因context为undefined直接抛出错误。

解决方案

1. 标记登录页面为客户端组件

在app/login/page.tsx顶部添加'use client',确保它能使用React客户端hooks:

'use client';

// 登录页面其余代码

2. 在Provider中处理Auth初始化状态

修改app/provider.tsx,添加加载状态避免在auth未就绪时渲染子组件,同时确保文件顶部的'use client'存在:

'use client';
import { useState, useEffect } from 'react';
// 其他必要导入...

const Provider = ({children}: { children: React.ReactNode }) => {
    const [auth, setAuth] = useState<Auth | undefined>(undefined);
    const [error, setError] = useState<Error | unknown>(undefined);
    const [isLoading, setIsLoading] = useState(true);
    // ...其他状态定义

    useEffect(() => {
        const initAuth = async () => {
            try {
                setAuth(new Auth());
            } catch (e) {
                setError(e);
            } finally {
                setIsLoading(false);
            }
        };
        if (!auth && !error) {
            initAuth();
        }
    }, []);

    // 加载中状态
    if (isLoading) {
        return <div>Loading...</div>;
    }

    // 初始化失败状态
    if (!auth && error) {
        return <div>Auth初始化失败: {error instanceof Error ? error.message : '未知错误'}</div>;
    }

    return (
        <ChakraProvider theme={theme} resetCSS cssVarsRoot="body">
            <ColorModeScript initialColorMode={theme.config.initialColorMode}/>
            <AuthContext.Provider value={auth}>
                <UserContext.Provider value={{user: user as User, setUser}}>
                    <ConfigContext.Provider value={{config: config as IPCConfig, setConfig}}>
                        <DriveContext.Provider
                            value={{
                                files,
                                setFiles,
                                sharedFiles,
                                setSharedFiles,
                                folders,
                                setFolders,
                                sharedPrograms,
                                setSharedPrograms,
                                programs,
                                setPrograms,
                                contacts,
                                setContacts,
                                path,
                                setPath,
                            }}
                        >
                            {children}
                        </DriveContext.Provider>
                    </ConfigContext.Provider>
                </UserContext.Provider>
            </AuthContext.Provider>
        </ChakraProvider>
    )
}

export default Provider;

3. 优化useAuthContext的错误逻辑

修改src/contexts/auth.ts,避免在服务器渲染或auth未初始化时直接抛出错误,让组件自行处理状态:

import {createContext, useContext} from 'react';
import Auth from 'lib/auth';

type AuthContextType = Auth | undefined;

const AuthContext = createContext<AuthContextType>(undefined);

const useAuthContext = (): Auth | undefined => {
    const context = useContext(AuthContext);
    // 返回上下文值,由使用组件判断是否就绪
    return context;
};

export { AuthContext, useAuthContext };

4. 确认Root Layout的Provider导入正确

确保app/layout.tsx中正确导入客户端组件Provider:

// app/layout.tsx
import Provider from './provider';

export default function RootLayout({children}: { children: React.ReactNode }) {
    return (
        <html lang="en">
        <body>
        <Provider>
            {children}
        </Provider>
        </body>
        </html>
    );
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 18:05:38