React Router:<Navigate>在if语句内失效,console.log正常问题求助
问题现象
编写的React登录组件中,表单提交验证通过时,console.log("Authentication successful!")正常输出,但<Navigate to="/home" />无法触发页面跳转;若直接在组件return中返回该组件则可正常工作。
问题原因
Navigate是React Router提供的声明式导航组件,它的生效逻辑是必须作为React元素被渲染到DOM树中,才能被React Router识别并执行导航操作。而在handleSubmit这类事件处理函数中直接返回<Navigate />,这个返回值并没有被React纳入渲染流程,自然无法触发跳转。
解决方法
方案一:使用useNavigate钩子(推荐)
React Router v6提供了useNavigate钩子,用于实现命令式导航,适合在事件处理函数中直接触发页面跳转。
修改后的完整代码:
import Typewriter from "typewriter-effect"; import { useNavigate } from "react-router-dom"; // 导入useNavigate import { useState } from "react"; const Login = () => { const [username, setUsername] = useState(""); const [password, setPassword] = useState(""); const navigate = useNavigate(); // 初始化导航函数 const handleUsernameChange = (event) => { setUsername(event.target.value); }; const handlePasswordChange = (event) => { setPassword(event.target.value); }; const handleSubmit = (event) => { event.preventDefault(); if (username === "name" && password === "123") { console.log("Authentication successful!"); navigate("/home"); // 调用导航函数完成跳转 } else { console.log("Authentication failed!"); } }; return ( <div className="flex justify-center items-center w-full h-screen bg-gradient-to-r from-lime-700 via-orange-900 to-red-800"> <div className=" w-[500px] h-[490px] text-white bg-black/20 rounded-2xl"> <div className="w-[400px] py-10 mx-auto"> <form onSubmit={handleSubmit} className="text-black"> <label> Username: <input type="text" value={username} onChange={handleUsernameChange} /> </label> <br /> <label> Password: <input type="password" value={password} onChange={handlePasswordChange} /> </label> <br /> <button>Submit</button> </form> </div> </div> </div> ); }; export default Login;
方案二:通过状态控制渲染Navigate组件
新增一个状态变量,控制Navigate组件是否被渲染到组件的输出树中,以此触发导航。
修改后的完整代码:
import Typewriter from "typewriter-effect"; import { Navigate } from "react-router-dom"; import { useState } from "react"; const Login = () => { const [username, setUsername] = useState(""); const [password, setPassword] = useState(""); const [isAuthenticated, setIsAuthenticated] = useState(false); // 新增认证状态 const handleUsernameChange = (event) => { setUsername(event.target.value); }; const handlePasswordChange = (event) => { setPassword(event.target.value); }; const handleSubmit = (event) => { event.preventDefault(); if (username === "name" && password === "123") { console.log("Authentication successful!"); setIsAuthenticated(true); // 标记认证成功 } else { console.log("Authentication failed!"); } }; // 认证成功时渲染Navigate组件触发跳转 if (isAuthenticated) { return <Navigate to="/home" />; } return ( <div className="flex justify-center items-center w-full h-screen bg-gradient-to-r from-lime-700 via-orange-900 to-red-800"> <div className=" w-[500px] h-[490px] text-white bg-black/20 rounded-2xl"> <div className="w-[400px] py-10 mx-auto"> <form onSubmit={handleSubmit} className="text-black"> <label> Username: <input type="text" value={username} onChange={handleUsernameChange} /> </label> <br /> <label> Password: <input type="password" value={password} onChange={handlePasswordChange} /> </label> <br /> <button>Submit</button> </form> </div> </div> </div> ); }; export default Login;
内容的提问来源于stack exchange,提问作者vvK
相关产品推荐
相关产品推荐

