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
额外优化点
- 修正输入框
type属性:原代码中type={"login"}为无效HTML属性,改为type="text" - 使用函数式
setState更新表单数据,避免闭包导致的状态更新错误 - 将
axios.post改为async/await写法,提升代码可读性和错误处理能力 - 添加输入框
placeholder,优化用户体验
其他注意事项
- 确保
AuthProvider配置正确,authName和authType符合业务需求 RequireAuth组件已正确包裹需要认证的路由(如/profile),无需额外修改
内容的提问来源于stack exchange,提问作者bogdan-byte
相关产品推荐
相关产品推荐

