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

React项目中useLocalStorage无效JSON报错的解决求助

解决useLocalStorage Hook读取时的JSON解析错误

问题根源

报错Error reading value for key auth: "undefined" is not valid JSON说明你的localStorage中auth键对应的存储值是字符串"undefined",而非JS原生的undefined或null。由于JSON规范中不存在undefined类型,执行JSON.parse("undefined")时会直接抛出解析错误。

你的空值判断仅排除了storedValue为null或undefined的情况,但未覆盖存储值是字符串"undefined"、空字符串这类无效JSON的场景。

修复步骤

1. 快速清除现有无效存储值

打开浏览器开发者工具的Console面板,执行以下命令清除错误的auth存储项:

localStorage.removeItem('auth')

这能立即解决当前页面的报错,避免后续加载时重复触发解析失败。

2. 增强useLocalStorage的健壮性

修改Hook代码,增加对无效JSON字符串的判断,同时在解析失败时自动清理无效存储值:

import { useState, useEffect } from "react";

export const useLocalStorage = (key, defaultValue) => {
  if (typeof window === 'undefined') {
    throw new Error("useLocalStorage hook can only be used in a browser environment.");
  }

  if (!key || typeof key !== "string") {
    throw new Error("Invalid key for useLocalStorage hook.");
  }

  const [value, setValue] = useState(() => {
    try {
      const storedValue = localStorage.getItem(key);

      // 排除null、undefined、空字符串、"undefined"字符串这些无效情况
      if (storedValue == null || storedValue.trim() === '' || storedValue === '"undefined"') {
        return defaultValue;
      }
      
      return JSON.parse(storedValue);
    } catch (error) {
      console.error(`Error reading value for key ${key}: ${error.message}`);
      // 解析失败时自动清除无效存储值,避免下次加载重复报错
      localStorage.removeItem(key);
      return defaultValue;
    }
  });

  useEffect(() => {
    const handleStorageChange = (event) => {
      if (event.key === key) {
        try {
          const newValue = event.newValue;
          // 同样处理storage事件中的无效值
          if (newValue == null || newValue.trim() === '' || newValue === '"undefined"') {
            setValue(defaultValue);
            return;
          }
          setValue(JSON.parse(newValue));
        } catch (error) {
          console.error(`Error parsing new value for key ${key}: ${error.message}`);
          localStorage.removeItem(key);
          setValue(defaultValue);
        }
      }
    };

    window.addEventListener("storage", handleStorageChange);
    
    return () => {
      window.removeEventListener("storage", handleStorageChange);
    };
  }, [key, defaultValue]);

  const setLocalStorageValue = (newValue) => {
    if (newValue === undefined || newValue === null) {
      throw new Error("Invalid value for useLocalStorage hook.");
    }
    try {
      localStorage.setItem(key, JSON.stringify(newValue));
      setValue(newValue);
    } catch (error) {
      console.error(`Error setting value for key ${key}: ${error.message}`);
    }
  };

  const clearLocalStorageValue = () => {
    try {
      localStorage.removeItem(key);
      setValue(defaultValue);
    } catch (error) {
      console.error(`Error clearing value for key ${key}: ${error.message}`);
    }
  };

  return [value, setLocalStorageValue, clearLocalStorageValue];
};

关键修改点说明

  • 初始化阶段:新增判断逻辑,排除"undefined"字符串、空字符串等无效值;解析失败时自动清除本地存储的无效项,避免后续加载重复报错。
  • storage事件监听:同步处理其他标签页传来的无效值,保证多标签页状态同步时的健壮性。
  • 依赖项更新:将defaultValue加入useEffect的依赖数组,确保defaultValue变化时状态能同步更新。

3. 检查存储逻辑(可选)

确认你的userLogout方法使用initialState(有效对象)进行状态重置,当前代码中setAuth(initialState)是正确的,不会生成无效JSON。如果之前存在直接存储undefined的逻辑(比如setAuth(undefined)),需修正为存储initialState或调用clearLocalStorageValue方法。

内容的提问来源于stack exchange,提问作者Stanislava Stoeva

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 08:13:09