用户注册后触发'Uncaught SyntaxError: "undefined" is not valid JSON'错误求助
注册后出现JSON解析错误
错误信息
Uncaught SyntaxError: "undefined" is not valid JSON at JSON.parse (<anonymous>) at ./src/context/Context.js (Context.js:5:1) at options.factory (react refresh:6:1) at __webpack_require__ (bootstrap:24:1) at fn (hot module replacement:62:1) at ./src/components/topbar/TopBar.jsx (SideMenu.jsx:23:1) at options.factory (react refresh:6:1) at __webpack_require__ (bootstrap:24:1) at fn (hot module replacement:62:1) at ./src/App.js (return-arrow.svg:26:1)
相关代码
Context.js
import { createContext, useEffect, useReducer } from "react"; import Reducer from "./Reducer"; const INITIAL_STATE = { user: JSON.parse(localStorage.getItem("user")) || null, isFetching: false, error: false, }; export const Context = createContext(INITIAL_STATE); export const ContextProvider = ({ children }) => { const [state, dispatch] = useReducer(Reducer, INITIAL_STATE); useEffect(() => { localStorage.setItem("user", JSON.stringify(state.user)); }, [state.user]); return ( <Context.Provider value={{ user: state.user, isFetching: state.isFetching, error: state.error, dispatch, }} > {children} </Context.Provider> ); };
Actions.js
export const RegisterStart = (userCredentials) => ({ type: "REGISTER_START", }); export const RegisterSuccess = (user) => ({ type: "REGISTER_SUCCESS", payload: user, }); export const RegisterFailure = () => ({ type: "REGISTER_FAILURE", });
注册页面提交函数
const handleSubmit = async (e) => { e.preventDefault(); dispatch({ type: "REGISTER_START" }); setError(false); try { const res = await axios.post("/register", { username, email, password, repeatPassword, }); dispatch({ type: "REGISTER_SUCCESS", payload: res.data }); } catch (err) { dispatch({ type: "REGISTER_FAILURE" }); setError(true); } };
问题定位与解决
核心原因
错误出在JSON.parse(localStorage.getItem("user")):当localStorage.getItem("user")返回字符串"undefined"时,JSON.parse无法解析(JSON规范中没有undefined类型,只有null)。
这种情况通常是因为存入localStorage时,state.user的值为undefined:JSON.stringify(undefined)会返回undefined,而localStorage.setItem会把这个undefined自动转为字符串"undefined"存入。
可能的触发场景
- 注册成功后,后端接口返回的
res.data为空或undefined,导致REGISTER_SUCCESS的payload是undefined,最终state.user变成undefined。 - Reducer中处理
REGISTER_SUCCESS时,错误地将user设为undefined。 - 注册失败时,
state.user可能被意外设为undefined(需检查Reducer逻辑)。
修复步骤
1. 修复localStorage存入逻辑(紧急修复)
修改Context.js中的useEffect,确保存入的始终是有效JSON:
useEffect(() => { // 当state.user为undefined时,转为null再序列化 localStorage.setItem("user", JSON.stringify(state.user || null)); }, [state.user]);
2. 修复初始状态解析逻辑
避免解析无效的"undefined"字符串:
const INITIAL_STATE = { user: (() => { const storedUser = localStorage.getItem("user"); // 排除"undefined"字符串,直接返回null if (!storedUser || storedUser === "undefined") return null; try { return JSON.parse(storedUser); } catch (e) { // 处理其他JSON解析错误,清理无效数据 localStorage.removeItem("user"); return null; } })(), isFetching: false, error: false, };
3. 检查注册接口返回值
确认后端/register接口在注册成功时,返回的是完整的用户对象,而非undefined或空值。可以在提交函数中临时打印验证:
try { const res = await axios.post("/register", { username, email, password, repeatPassword, }); console.log("注册返回数据:", res.data); // 检查输出是否为有效用户对象 dispatch({ type: "REGISTER_SUCCESS", payload: res.data }); } catch (err) { // ... }
4. 检查Reducer逻辑
确保REGISTER_SUCCESS和REGISTER_FAILURE的处理不会将user设为undefined:
// 示例Reducer逻辑,根据实际情况调整 const Reducer = (state, action) => { switch (action.type) { case "REGISTER_START": return { ...state, isFetching: true, error: false, }; case "REGISTER_SUCCESS": return { ...state, isFetching: false, user: action.payload || null, // 确保不会是undefined }; case "REGISTER_FAILURE": return { ...state, isFetching: false, error: true, user: null, // 失败时重置为null,而非undefined }; default: return state; } };
内容的提问来源于stack exchange,提问作者sultan.h
相关产品推荐
相关产品推荐

