React中如何将allLists变更保存到localStorage,刷新数据失效如何解决
问题原因
- localStorage 仅支持存储字符串类型,你直接把数组/对象类型传入
localStorage.setItem时,值会被自动调用toString()方法转为[object Array]这类无意义的字符串,无法还原为原始的列表结构 - 你当前实现的hook默认mapper直接返回原始字符串,没有做反序列化处理,页面刷新后从localStorage取到的是异常字符串,不是你期望的列表结构
- 补充:你调用hook时传入的默认值是
[initialLists],如果initialLists本身就是数组,额外套一层数组也可能导致结构不符合预期,需要根据业务逻辑核对
修复方案
第一步:改造useLocalStorage hook,默认增加序列化/反序列化处理
import { useState } from 'react'; export function useLocalStorage(key, defaultValue, mapper = JSON.parse) { const getInitialValue = () => { const storedValue = localStorage.getItem(key); if (storedValue !== null) { try { // 增加异常捕获,避免存储内容不合法导致页面报错 return mapper(storedValue); } catch (e) { console.warn(`localStorage key ${key} 存储内容非法,已使用默认值`, e); // 异常情况可选择清除非法存储 localStorage.removeItem(key); return defaultValue; } } return defaultValue; }; const [value, setValue] = useState(getInitialValue); const setAndStoreValue = (newValue) => { setValue(newValue); // 存储前做序列化处理,支持对象/数组等类型 const valueToStore = typeof newValue === 'string' ? newValue : JSON.stringify(newValue); localStorage.setItem(key, valueToStore); }; return [value, setAndStoreValue]; }
如果你的业务不需要拦截空字符串存储,可以移除原逻辑里对应的非空判断,避免需要存储空值时无法写入。
第二步:核对调用逻辑
如果你的initialLists本身就是初始化的列表数组,调用时不需要额外套一层数组,调整为:
const [allLists, setAllLists] = useLocalStorage('allLists', initialLists);
如果有自定义的序列化需求,传入对应的mapper函数覆盖默认的JSON.parse即可。
内容的提问来源于stack exchange,提问作者CookieMonster
相关产品推荐
相关产品推荐

