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

使用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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 01:20:42