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

React 18+React Router 6+React Auth Kit登录组件更新报错求助

解决React Auth Kit + React Router 6的"Cannot update a component while rendering a different component"错误

问题场景

使用React 18、React Router 6和React Auth Kit 2.7开发登录页面,参照官方示例实现时,出现"Cannot update a component while rendering a different component"错误。

错误原因

在SignInComponent的渲染阶段直接调用isAuthenticated(),该函数会触发React Auth Kit内部的状态订阅更新,违反了React的渲染规则——渲染阶段不能触发状态更新。React 18的严格模式会严格检测这类操作并抛出错误。

解决方案

核心思路

将认证状态的检查从渲染阶段移到组件挂载后的副作用阶段,用状态变量存储认证状态,避免渲染期间触发状态更新。

修改后的登录组件代码

import React, { useEffect, useState } from "react"
import axios from "axios"
import { useIsAuthenticated, useSignIn } from "react-auth-kit"
import { useNavigate, Navigate } from "react-router-dom"

const SignInComponent = () => {
  const isAuthenticated = useIsAuthenticated()
  const signIn = useSignIn()
  const navigate = useNavigate()
  const [formData, setFormData] = useState({ login: "", password: "" })
  // 用状态变量存储认证状态,避免渲染时直接调用isAuthenticated()
  const [isAuth, setIsAuth] = useState(false)

  // 在组件挂载后检查认证状态
  useEffect(() => {
    const authStatus = isAuthenticated()
    setIsAuth(authStatus)
  }, [isAuthenticated])

  // 优化表单更新,使用函数式setState避免闭包问题
  const handleInputChange = (field) => (e) => {
    setFormData(prev => ({ ...prev, [field]: e.target.value }))
  }

  async function onSubmit(e) {
    e.preventDefault()
    try {
      const res = await axios.post("http://localhost:3030/api/auth/login", formData)
      if (res.status === 200) {
        const signInSuccess = signIn({
          token: res.data.token,
          expiresIn: res.data.expiresIn,
          tokenType: "Bearer",
          authState: res.data.authUserState,
        })
        if (signInSuccess) {
          navigate("/profile")
          console.log("logged in")
        } else {
          // 处理登录失败逻辑
          console.error("登录失败:令牌无效")
        }
      } else {
        console.error("登录请求失败")
      }
    } catch (err) {
      console.error("登录请求出错:", err)
    }
  }

  if (isAuth) {
    return <Navigate to={"/profile"} replace />
  }

  return (
    <form onSubmit={onSubmit} className="flex flex-col w-96 p-2">
      <input
        className="text-black mt-2"
        type="text" // 修正无效的login类型,改用text
        placeholder="登录名"
        value={formData.login}
        onChange={handleInputChange("login")}
      />
      <input
        className="text-black mt-2"
        type="password"
        placeholder="密码"
        value={formData.password}
        onChange={handleInputChange("password")}
      />
      <button type="submit" className="mt-4">登录</button>
    </form>
  )
}

export default SignInComponent

额外优化点

  1. 修正输入框type属性:原代码中type={"login"}为无效HTML属性,改为type="text"
  2. 使用函数式setState更新表单数据,避免闭包导致的状态更新错误
  3. 将axios.post改为async/await写法,提升代码可读性和错误处理能力
  4. 添加输入框placeholder,优化用户体验

其他注意事项

  • 确保AuthProvider配置正确,authName和authType符合业务需求
  • RequireAuth组件已正确包裹需要认证的路由(如/profile),无需额外修改

内容的提问来源于stack exchange,提问作者bogdan-byte

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 07:25:22