Local Storage 本地存储
·
🧠 一、什么是 Local Storage?
Local Storage(本地存储) 是浏览器提供的一种 Web Storage API,用于在用户浏览器中存储 键值对(key-value) 数据,特点如下:
| 特性 | 说明 |
|---|---|
| 存储位置 | 浏览器本地 |
| 生命周期 | 永久存储,除非手动清除或代码删除 |
| 存储容量 | 一般为 5MB~10MB(不同浏览器略有差异) |
| 作用域 | 同源策略(相同协议+域名+端口)下共享 |
| 是否支持同步读写 | ✅ 是(但不要滥用,大量读写可能阻塞 UI) |
| 是否支持复杂对象 | ❌ 默认只能存字符串,需手动 JSON 序列化/反序列化 |
对比:
- LocalStorage:长期保存,同源共享
- SessionStorage:标签页级,关闭标签页后失效
- Cookie:小数据,随请求发送给服务器
🛠️ 二、在 Vite + React 中使用 Local Storage
✅ 1. 基本用法:读写字符串
写入数据(保存):
localStorage.setItem('key', 'value');
读取数据:
const value = localStorage.getItem('key');
console.log(value); // 'value'
删除某个数据:
localStorage.removeItem('key');
清空所有本地存储:
localStorage.clear();
✅ 2. 存储复杂数据(如对象、星系介绍)
由于 localStorage 只能存字符串,如果要存对象(如星系介绍的 JSON 数据),需要:
- 存的时候:用
JSON.stringify()转成字符串 - 取的时候:用
JSON.parse()转回对象
示例:存储和读取一个星系介绍对象
import { useEffect, useState } from 'react';
function GalaxyInfo() {
const [galaxy, setGalaxy] = useState(null);
const [name, setName] = useState('');
const [description, setDescription] = useState('');
// 组件挂载时,从 localStorage 读取数据
useEffect(() => {
const savedGalaxy = localStorage.getItem('galaxyInfo');
if (savedGalaxy) {
const parsed = JSON.parse(savedGalaxy);
setGalaxy(parsed);
setName(parsed.name);
setDescription(parsed.description);
}
}, []);
// 保存数据到 localStorage
const saveGalaxy = () => {
const info = { name, description };
setGalaxy(info);
localStorage.setItem('galaxyInfo', JSON.stringify(info));
alert('星系信息已保存!');
};
return (
<div style={{ padding: 20 }}>
<h2>星系介绍</h2>
<div>
<label>星系名称:</label>
<input
type="text"
value={name}
onChange={(e) => setName(e.target.value)}
style={{ marginLeft: 8 }}
/>
</div>
<br />
<div>
<label>介绍:</label>
<textarea
value={description}
onChange={(e) => setDescription(e.target.value)}
style={{ marginLeft: 8, width: '300px', height: '100px' }}
/>
</div>
<br />
<button onClick={saveGalaxy}>保存星系信息</button>
{galaxy && (
<div style={{ marginTop: 20, border: '1px solid #ccc', padding: 10 }}>
<h3>已保存的星系信息:</h3>
<p><strong>名称:</strong>{galaxy.name}</p>
<p><strong>介绍:</strong>{galaxy.description}</p>
</div>
)}
</div>
);
}
export default GalaxyInfo;
🧩 三、封装成自定义 Hook(推荐)
为了在多个组件中复用 Local Storage 的逻辑,建议封装成一个 自定义 Hook,例如 useLocalStorage。
✅ 自定义 useLocalStorage Hook 示例:
// src/hooks/useLocalStorage.js
import { useState, useEffect } from 'react';
function useLocalStorage(key, initialValue) {
// 从 localStorage 读取初始值
const [storedValue, setStoredValue] = useState(() => {
try {
const item = localStorage.getItem(key);
return item ? JSON.parse(item) : initialValue;
} catch (error) {
console.error('读取 localStorage 出错:', error);
return initialValue;
}
});
// 更新 localStorage
const setValue = (value) => {
try {
setStoredValue(value);
localStorage.setItem(key, JSON.stringify(value));
} catch (error) {
console.error('写入 localStorage 出错:', error);
}
};
return [storedValue, setValue];
}
export default useLocalStorage;
✅ 使用这个 Hook(以星系信息为例):
import { useEffect } from 'react';
import useLocalStorage from './hooks/useLocalStorage';
function GalaxyInfo() {
const [galaxy, setGalaxy] = useLocalStorage('galaxyInfo', null);
const [name, setName] = useState('');
const [description, setDescription] = useState('');
useEffect(() => {
if (galaxy) {
setName(galaxy.name || '');
setDescription(galaxy.description || '');
}
}, [galaxy]);
const saveGalaxy = () => {
const info = { name, description };
setGalaxy(info);
};
return (
<div style={{ padding: 20 }}>
<h2>星系介绍</h2>
<div>
<label>星系名称:</label>
<input
type="text"
value={name}
onChange={(e) => setName(e.target.value)}
style={{ marginLeft: 8 }}
/>
</div>
<br />
<div>
<label>介绍:</label>
<textarea
value={description}
onChange={(e) => setDescription(e.target.value)}
style={{ marginLeft: 8, width: '300px', height: '100px' }}
/>
</div>
<br />
<button onClick={saveGalaxy}>保存星系信息</button>
{galaxy && (
<div style={{ marginTop: 20, border: '1px solid #ccc', padding: 10 }}>
<h3>已保存的信息:</h3>
<p><strong>名称:</strong>{galaxy.name}</p>
<p><strong>介绍:</strong>{galaxy.description}</p>
</div>
)}
</div>
);
}
export default GalaxyInfo;
🧼 四、注意事项
| 注意事项 | 说明 |
|---|---|
| 只能存字符串 | 对象/数组必须用 JSON.stringify() 和 JSON.parse() 处理 |
| 同步操作 | 不要在高频循环/动画中频繁读写,可能影响性能 |
| 同源策略 | 只能在相同协议+域名+端口的页面间共享 |
| 容量限制 | 一般为 5~10MB,不适合存大量数据(如图片、视频) |
| 隐私模式 | 某些浏览器隐私模式下可能禁用或限制 localStorage |
| SSR 不兼容 | 在 Next.js 等 SSR 框架中,不要在服务端直接调用 localStorage(会报错),需要做 typeof window !== 'undefined' 判断 |
🎁 五、扩展:存储多个星系(数组形式)
如果你想存储多个星系介绍,可以用 数组:
// 保存多个星系
const galaxies = [
{ id: 1, name: '银河系', desc: '我们所在的星系' },
{ id: 2, name: '仙女座星系', desc: '距离我们最近的大星系' },
];
localStorage.setItem('galaxies', JSON.stringify(galaxies));
// 读取
const saved = JSON.parse(localStorage.getItem('galaxies'));
console.log(saved);
✅ 总结
| 功能 | 实现方式 |
|---|---|
| 保存数据到 LocalStorage | localStorage.setItem('key', JSON.stringify(value)) |
| 从 LocalStorage 读取数据 | JSON.parse(localStorage.getItem('key')) |
| 删除某个数据 | localStorage.removeItem('key') |
| 清空所有数据 | localStorage.clear() |
| 在 React 中使用 | 推荐用 useState + useEffect,或封装成 useLocalStorage 自定义 Hook |
| 存储复杂对象(如星系介绍) | 必须 JSON 序列化与反序列化 |
| 最佳实践 | 封装复用、避免频繁读写、注意同源和容量限制 |
更多推荐



所有评论(0)