使用useLocation()读取state遇空值错误,寻求修复方案
问题分析
你遇到的Cannot read properties of null (reading 'mes')错误,本质是手动访问/profile路由时,location.state不存在(为null),但你直接尝试读取location.state.mes,触发了类型错误。
另外补充一个潜在隐患:Login组件中使用<Navigate>时,success是通过setSuccess更新的状态,而setState是异步操作,可能出现跳转时success还未更新的情况,导致传递的mes为空字符串。
解决方案
1. 给location.state添加空值保护(核心修复)
使用可选链操作符?. 配合默认值,避免直接访问null/undefined的属性:
修改Profile.jsx:
import { useState } from "react"; import { useLocation } from "react-router-dom"; function Profile() { const location = useLocation(); // 用可选链+默认值,确保msg不会抛出错误 const msg = location.state?.mes || ""; const [success, setSuccess] = useState(msg); const [cancel, setCancel] = useState(msg ? "X" : ""); const [name, setName] = useState( msg ? "h-10 flex justify-around items-center bg-green-200 text-black" : "" ); function handleClick() { setSuccess(""); setCancel(""); setName(""); } return ( <> {success && ( <div className={name}> {success} <button onClick={handleClick}>{cancel}</button> </div> )} profile </> ); } export default Profile;
2. 修复Login组件异步状态更新问题
因为setSuccess是异步的,直接在setResult(true)后跳转可能导致success未更新完成。改用useEffect监听状态变化,再执行跳转:
修改Login.jsx:
import { useState, useEffect } from "react"; import { Link, Navigate, Outlet } from "react-router-dom"; import axios from "axios"; import { FaEye, FaEyeSlash } from "react-icons/fa"; function Login() { const [email, setEmail] = useState(""); const [password, setPassword] = useState(""); const [inputType, setInputType] = useState("password"); const [icon, setIcon] = useState(<FaEye />); const [success, setSuccess] = useState(""); const [result, setResult] = useState(false); // ... 原handleToggle、handleSubmit函数不变 // 监听result和success的变化,确保状态更新后再跳转 useEffect(() => { if (result) { // 此处success已完成更新 } }, [result, success]); return ( <> {result && <Navigate to="/profile" state={{ mes: success }} />} <form onSubmit={handleSubmit}> {/* 原表单内容不变 */} <div className="text-center text-lg text-red-500 font-semibold">{success}</div> <div className="h-auto w-5/12 border mx-auto rounded-2xl mt-3 "> <div className="h-2 bg-indigo-400 rounded-t-2xl mb-5 "></div> <div className="font-bold text-2xl text-center">Sign In</div> <div className="px-16"> <div className="mt-5 "> <label htmlFor="email" className="block font-semibold "> Email address </label> <input type="email" className="border h-5 w-full px-3 py-5 rounded-md focus:outline-2 focus:outline-blue-600" value={email} onChange={(e) => setEmail(e.target.value)} placeholder="Enter email" id="email" required /> </div> <div className="relative "> <label htmlFor="pass" className="block font-semibold mt-5" > Password </label> <input type={inputType} className="border h-5 w-full px-3 py-5 rounded-md focus:outline-2 focus:outline-blue-600" value={password} onChange={(e) => setPassword(e.target.value)} placeholder="Enter password" id="pass" required /> <span className="absolute top-9 right-6" onClick={handleToggle}> {icon} </span> </div> <div className=""> <button type="submit" className="mt-5 text-white bg-blue-600 border h-10 w-full py-2 rounded-md" > Submit </button> </div> <div className="flex justify-around"> <p className="mb-5 mt-3 text-left"> New here? <Link to="/sign-up" className="text-blue-600"> Register </Link> </p> <p className="mb-5 mt-3 text-right "> Forgot <Link to="/password-reset" className="text-blue-600"> password? </Link> </p> </div> </div> </div> </form> </> ); } export default Login;
3. 可选:无state时重定向到登录页
如果业务要求必须从登录页跳转进入Profile,可在Profile组件中判断,无state则重定向:
import { useState } from "react"; import { useLocation, Navigate } from "react-router-dom"; function Profile() { const location = useLocation(); // 无state时强制跳转回登录页 if (!location.state) { return <Navigate to="/login" />; } const msg = location.state.mes; // ... 剩余代码不变 }
内容的提问来源于stack exchange,提问作者ayex
相关产品推荐
相关产品推荐

