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

页面刷新后LocalStorage自定义播放列表丢失问题排查

问题分析与修复方案

核心问题1:Set对象无法被JSON序列化

JSON.stringify无法正确处理Set类型,会将其序列化为空对象{}。这意味着你存入LocalStorage的播放列表数据实际上是空的,根本没保存有效内容。

核心问题2:组件挂载时的LocalStorage覆盖

组件初始化时,useState会创建包含两个Set的初始playlists对象,依赖sidebarState.playlists的useEffect会在挂载时执行,将这个初始(序列化后为空对象)的playlists存入LocalStorage,直接覆盖掉之前用户自定义的播放列表数据。

核心问题3:状态更新时丢失其他属性

在读取LocalStorage的useEffect中,你直接用setSidebarState({ playlists: JSON.parse(data) })更新状态,这会完全替换原有sidebarState,导致currentPlaylist、modal、succes这些属性丢失。


修复步骤

1. 替换Set为数组,解决序列化问题

将播放列表的存储从Set改为普通数组,数组可被JSON正常序列化和反序列化:

const [sidebarState, setSidebarState] = useState({
  currentPlaylist: 'home',
  modal: false,
  playlists: { home: [], favorites: [] }, // 把Set换成数组
  succes: ''
});

后续操作播放列表时,用数组的push、filter等方法替代Set的add、delete即可。

2. 调整初始化逻辑,避免默认值覆盖

在初始化状态时优先读取LocalStorage,只有当LocalStorage为空时才使用默认值,彻底避免初始值覆盖自定义数据:

// 初始化状态优先从LocalStorage读取
const initialState = () => {
  const storedData = localStorage.getItem('MUSIC_LIBRARY_APP');
  if (storedData) {
    return {
      currentPlaylist: 'home',
      modal: false,
      playlists: JSON.parse(storedData),
      succes: ''
    };
  }
  // LocalStorage为空时才用默认值
  return {
    currentPlaylist: 'home',
    modal: false,
    playlists: { home: [], favorites: [] },
    succes: ''
  };
};

const [sidebarState, setSidebarState] = useState(initialState);

这样可以去掉原有的第二个useEffect,简化逻辑同时避免状态冲突。

3. 保留播放列表变化时的自动存储

播放列表内容变化时,正常写入LocalStorage即可:

useEffect(() => {
  localStorage.setItem('MUSIC_LIBRARY_APP', JSON.stringify(sidebarState.playlists));
}, [sidebarState.playlists]);

最终优化后的代码示例

// 初始化状态优先从LocalStorage读取
const initialState = () => {
  const storedData = localStorage.getItem('MUSIC_LIBRARY_APP');
  if (storedData) {
    return {
      currentPlaylist: 'home',
      modal: false,
      playlists: JSON.parse(storedData),
      succes: ''
    };
  }
  return {
    currentPlaylist: 'home',
    modal: false,
    playlists: { home: [], favorites: [] },
    succes: ''
  };
};

const [sidebarState, setSidebarState] = useState(initialState);

// 播放列表变化时自动存入LocalStorage
useEffect(() => {
  localStorage.setItem('MUSIC_LIBRARY_APP', JSON.stringify(sidebarState.playlists));
}, [sidebarState.playlists]);

内容的提问来源于stack exchange,提问作者Mees Goudbeek

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 07:50:25