React应用JSON.parse报错Unexpected token u in JSON at position 0
错误原因
报错Uncaught SyntaxError: Unexpected token u in JSON at position 0的核心触发逻辑如下:
- 当应用首次加载、localStorage中从未存储过
user字段时,localStorage.getItem("user")会直接返回undefined - 代码未做判空处理直接将
undefined传入JSON.parse(),JS会先将undefined转为字符串"undefined",JSON解析器读取第一个字符u时发现不符合JSON语法规则,直接抛出语法错误 - 除了首次加载的场景,如果localStorage中的
user字段被手动修改为非合法JSON格式的脏数据,也会触发同类JSON解析错误
修复方案
核心思路是给localStorage的读取操作增加判空校验+解析异常兜底,避免非法值直接传入JSON.parse。
- 新增安全读取存储用户信息的方法,替换原有直接解析的逻辑,修复后的核心代码如下:
import { createContext, useEffect, useReducer } from "react"; // 安全读取本地缓存的用户信息 const getStoredUser = () => { const userStr = localStorage.getItem("user"); // 无缓存值直接返回null,避免传入undefined触发解析错误 if (!userStr) return null; try { return JSON.parse(userStr); } catch (error) { // 遇到非法JSON格式的脏数据时,清除坏缓存兜底 localStorage.removeItem("user"); return null; } }; const INITIAL_STATE = { user: getStoredUser(), loading: false, error: null, }; export const AuthContext = createContext(INITIAL_STATE); const AuthReducer = (state, action) => { switch (action.type) { case "LOGIN_START": return { user: null, loading: true, error: null, }; case "LOGIN_SUCCESS": return { user: action.payload, loading: false, error: null, }; case "LOGIN_FAILURE": return { user: null, loading: false, error: action.payload, }; case "LOGOUT": return { user: null, loading: false, error: null, }; default: return state; } }; export const AuthContextProvider = ({ children }) => { const [state, dispatch] = useReducer(AuthReducer, INITIAL_STATE); useEffect(() => { // 登出时state.user为null,序列化后存入localStorage是合法JSON字符串,不会触发解析问题 localStorage.setItem("user", JSON.stringify(state.user)); }, [state.user]); return ( <AuthContext.Provider value={{ user: state.user, loading: state.loading, error: state.error, dispatch, }} > {children} </AuthContext.Provider> ); };
- 额外优化:原代码中
import React, { Component } from 'react';属于冗余导入,当前实现全部基于React Hook编写,未使用类组件的ComponentAPI,可以直接删除,减少不必要的打包体积。
内容的提问来源于stack exchange,提问作者Teo Suciu
相关产品推荐
相关产品推荐

