React报错:Cannot set properties of undefined (setting 'full_name')原因咨询
React项目Uncaught TypeError报错分析与解决
问题详情
- 报错:
Uncaught TypeError: Cannot set properties of undefined (setting 'full_name'),触发位置为handleSubmit函数内的obj.full_name = name;行 - 疑问:该行报错后,后续的
obj.email = email;等赋值操作为何未触发同类错误
相关代码
import React, { useState, useEffect } from "react"; import JSONDATA from "../data/MOCK_DATA.json"; import { useNavigate } from "react-router-dom"; const Edit = () => { const [name, setName] = useState(""); const [email, setEmail] = useState(""); const [role, setRole] = useState(""); const [location, setLocation] = useState(""); const [id, setId] = useState(""); let navigate = useNavigate(); var index = JSONDATA.map((e) => { return e.id; }).indexOf(id); const handleSubmit = (e) => { e.preventDefault(); let obj = JSONDATA[index]; obj.full_name = name; obj.email = email; obj.role = role; obj.location = location; navigate("/"); }; useEffect(() => { setId(localStorage.getItem("id")); setName(localStorage.getItem("name")); setEmail(localStorage.getItem("email")); setRole(localStorage.getItem("role")); setLocation(localStorage.getItem("location")); }, []); return ( <div className="w-full h-[45rem] max-w-[1500px] mx-auto"> <h1 className="flex justify-center items-center text-3xl pt-[7rem] font-semibold text-orange-600 mx-auto"> Edit a new listing </h1> <form className="gap-10 flex h-full flex-col mx-auto justify-center items-center" onSubmit={handleSubmit} > <input className=" bg-gray-200 my-2 px-4 rounded-2xl shadow-xl" placeholder="Full Name" type="text" id="name" name="name" value={name} onChange={(e) => setName(e.target.value)} /> <input className=" bg-gray-200 my-2 px-4 rounded-2xl shadow-xl" placeholder="Email" type="email" id="email" name="email" value={email} onChange={(e) => setEmail(e.target.value)} /> <input className=" bg-gray-200 my-2 px-4 rounded-2xl shadow-xl" placeholder="Role" type="text" id="role" name="role" value={role} onChange={(e) => setRole(e.target.value)} /> <input className=" bg-gray-200 my-2 px-4 rounded-2xl shadow-xl" placeholder="Location" type="text" id="location" name="location" value={location} onChange={(e) => setLocation(e.target.value)} /> <button className="my-2 px-4 py-3 bg-blue-300 active:bg-blue-500 rounded-2xl shadow-xl" type="submit" onSubmit={handleSubmit} > Update </button> </form> </div> ); }; export default Edit;
问题原因
- 代码执行中断:JavaScript是单线程执行模式,当运行到
obj.full_name = name;时,发现obj为undefined会立即抛出错误并终止函数执行,后续赋值语句根本不会运行,因此不会触发同类报错。 - obj为undefined的根源:
- 组件初始化时
id的初始值是空字符串"",此时计算index会得到-1(JSONDATA中无id为空的项)。 - 虽然
useEffect会从localStorage获取id并更新id状态,但组件初始化时计算的index不会自动更新,导致JSONDATA[index]即JSONDATA[-1]返回undefined。
- 组件初始化时
解决方案
方案1:在handleSubmit内实时计算index
确保每次提交时使用最新的id值获取正确索引:
const handleSubmit = (e) => { e.preventDefault(); // 实时计算索引 const index = JSONDATA.map(e => e.id).indexOf(id); // 处理找不到对应数据的情况 if (index === -1) { console.error("未找到对应ID的数据"); return; } let obj = JSONDATA[index]; obj.full_name = name; obj.email = email; obj.role = role; obj.location = location; navigate("/"); };
方案2:用useMemo监听id变化自动更新index
借助useMemo实现index随id状态自动更新:
import React, { useState, useEffect, useMemo } from "react"; // ...其他导入 const Edit = () => { // ...状态定义 // 监听id变化,自动更新index const index = useMemo(() => { return JSONDATA.map(e => e.id).indexOf(id); }, [id]); // ...handleSubmit函数 };
额外优化:类型转换与边界处理
如果JSONDATA中的id是数字类型,而localStorage获取的是字符串,需要转换类型后再查找:
const index = JSONDATA.map(e => e.id).indexOf(Number(id));
内容的提问来源于stack exchange,提问作者AshdodyBoy
相关产品推荐
相关产品推荐

