调用useSelector出现Invalid hook call无效Hook调用错误如何解决?
报错原因
- React Hook 有严格的调用限制,仅允许在两个场景下调用:React 函数组件的顶层函数体、自定义 Hook 的顶层函数体
- 你代码中调用
useSession()的位置是 Next.jsgetServerSideProps逻辑内部,该函数是服务端运行的生命周期方法,不属于 React 组件的运行上下文,因此触发非法 Hook 调用报错。
解决方法
根据你的业务需求可以选择两种方案:
方案1:服务端获取 session(保留getServerSideProps登录校验逻辑)
移除getServerSideProps中的Hook调用,改为直接从服务端请求上下文提取session数据:
- redux 是客户端状态管理工具,其提供的
useSelectorHook 仅能在客户端 React 运行时使用,服务端无法直接调用。 - 通常 session 信息会存储在 cookie 中,你可以从
ctx.req.headers.cookie中解析出session标识,再校验得到session数据,示例代码如下:
import { parse } from 'cookie'; // 替换为你自己的session校验逻辑方法 import { verifySession } from './utils/session'; export const getServerSideProps = options => gssp => { const { signedIn, redirectTo } = options; return async ctx => { // 替换原来的useSession调用,改为服务端侧获取session const cookieStr = ctx.req.headers.cookie || '' const cookies = parse(cookieStr) const session = await verifySession(cookies.sessionId) if (signedIn && !session) { return { redirect: { destination: redirectTo || '/login', permanent: false, } } } const result = await gssp(ctx); return { ...result, props: { ...result.props, session, }, } } };
方案2:客户端做登录态校验
如果不需要服务端做登录拦截,把登录判断逻辑迁移到页面组件内部调用useSession即可:
// 页面组件示例 import { useSession } from './useSession'; import { useEffect } from 'react'; import { useRouter } from 'next/router'; export default function ProtectedPage() { const session = useSession(); const router = useRouter(); useEffect(() => { if (!session) { router.replace('/login') } }, [session, router]) if (!session) return null // 后续页面渲染逻辑 }
内容的提问来源于stack exchange,提问作者Anna
相关产品推荐
相关产品推荐

