如何在React Hook外使用useNavigate?解决路由重定向报错
问题分析与修复
这个报错的核心原因是你在组件渲染阶段直接调用了navigate(),React不允许在渲染另一个组件的同时更新BrowserRouter这类路由组件。你现在的emailCheck()和direct()直接写在组件顶层,组件每次渲染都会执行这两个函数,初始渲染时就触发路由跳转,违反了React的渲染流程规则。
另外还有个隐藏问题:用let hasEmail = false存储检查结果是普通变量,不是React状态,当邮箱列表加载完成后,变量变化不会触发组件重新渲染,逻辑可能出现不一致。
修复后的代码
const navigate = useNavigate(); const [emailList, setEmailList] = useState([]); const emailRef = collection(db, "emails"); // 用state存储检查结果,确保状态变化能触发组件更新 const [hasEmail, setHasEmail] = useState(false); useEffect(() => { const getEmails = async () => { const data = await getDocs(emailRef); setEmailList( data.docs.map((doc) => ({ ...doc.data(), })) ); }; getEmails(); }, []); // 把邮箱检查和跳转逻辑放到useEffect里,依赖emailList和当前用户 useEffect(() => { // 先判断当前用户是否存在,避免auth.currentUser为null时报错 if (!auth.currentUser) return; const checkEmailExists = emailList.some(e => e.email === auth.currentUser.email); setHasEmail(checkEmailExists); // 根据检查结果跳转 if (checkEmailExists) { navigate("/index"); } else { navigate("/enterdetails"); } }, [emailList, auth.currentUser, navigate]); // 添加必要的依赖项
关键修改点
- 把
hasEmail改成React状态useState(false),保证状态变化能驱动组件重新渲染 - 将邮箱检查和路由跳转逻辑移到
useEffect中,只有当emailList、auth.currentUser或navigate变化时才执行,避免在渲染阶段触发路由更新 - 增加了
auth.currentUser的空值判断,防止用户未登录时出现Cannot read property 'email' of null的错误
内容的提问来源于stack exchange,提问作者arw_29
相关产品推荐
相关产品推荐

