React usePersistedState钩子
返回一个在localStorage
中持久化的状态值和一个更新它的函数。
- 使用
useState()
钩子将value
初始化为defaultValue
。 - 使用
useRef()
钩子创建一个引用,用于保存Window.localStorage
中值的name
。 - 使用3个
useEffect()
钩子实现初始化、value
变化和name
变化。 - 当组件首次挂载时,使用
Storage.getItem()
更新value
,如果有存储的值,则使用Storage.setItem()
持久化当前值。 - 当
value
更新时,使用Storage.setItem()
存储新值。 - 当
name
更新时,使用Storage.setItem()
创建新的键,更新nameRef
,并使用Storage.removeItem()
从Window.localStorage
中删除前一个键。
[!NOTE]
该钩子适用于原始值(即非对象),并且不考虑由于其他代码而导致的
Window.localStorage
的更改。这两个问题都可以很容易地处理(例如JSON序列化和处理'storage'
事件)。
const usePersistedState = (name, defaultValue) => {
const [value, setValue] = React.useState(defaultValue);
const nameRef = React.useRef(name);
React.useEffect(() => {
try {
const storedValue = localStorage.getItem(name);
if (storedValue !== null) setValue(storedValue);
else localStorage.setItem(name, defaultValue);
} catch {
setValue(defaultValue);
}
}, []);
React.useEffect(() => {
try {
localStorage.setItem(nameRef.current, value);
} catch {}
}, [value]);
React.useEffect(() => {
const lastName = nameRef.current;
if (name !== lastName) {
try {
localStorage.setItem(name, value);
nameRef.current = name;
localStorage.removeItem(lastName);
} catch {}
}
}, [name]);
return [value, setValue];
};
const MyComponent = ({ name }) => {
const [val, setVal] = usePersistedState(name, 10);
return (
<input
value={val}
onChange={e => {
setVal(e.target.value);
}}
/>
);
};
const MyApp = () => {
const [name, setName] = React.useState('我的值');
return (
<>
<MyComponent name={name} />
<input
value={name}
onChange={e => {
setName(e.target.value);
}}
/>
</>
);
};
ReactDOM.createRoot(document.getElementById('root')).render(
<MyApp />
);