返回一个持久化在localStorage中的有状态值,以及一个更新它的函数。
- 使用useState()钩子将该值初始化为defaultValue。
- 使用useRef()钩子创建一个引用,该引用将保存Window.localStorage中的值的名称。
- 使用三个useEffect()钩子的实例分别进行初始化、值更改和名称更改。
- 当组件第一次挂载时,如果有存储值,则使用Storage.getItem()来更新值,或者使用Storage.setItem()来持久化当前值。
- 当value被更新时,使用Storage.setItem()来存储新值
- 当名称更新时,使用Storage.setItem()创建新的密钥,更新nameRef并使用Storage.removeItem()从windows . localstorage中删除之前的密钥。
注意:该钩子是用于原始值(即不是对象)的,不考虑对Window的更改。localStorage由于其他代码。这两个问题都很容易处理(例如JSON序列化和处理“存储”事件)。
import { useState,useRef, useEffect } from "react"
const usePersistedState = (name: string, defaultValue: string) => {
const [value, setValue] = useState(defaultValue)
const nameRef = useRef(name)
useEffect(()=>{
try {
const storedValue = localStorage.getItem(name)
if (storedValue !== null) {
setValue(storedValue)
} else {
localStorage.setItem(name, defaultValue)
}
} catch {
setValue(defaultValue)
}
}, [])
useEffect(()=>{
try {
localStorage.setItem(nameRef.current, value)
} catch {
}
}, [value])
useEffect(()=>{
const lastName = nameRef.current;
if (name !== lastName) {
try {
localStorage.setItem(name, value)
nameRef.current = name;
localStorage.removeItem(lastName)
} catch {
}
}
}, [name])
return [ value, setValue]
}
export default usePersistedState
Example
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('my-value');
return (
<>
<MyComponent name={name} />
<input
value={name}
onChange={e => {
setName(e.target.value);
}}
/>
</>
);
};
ReactDOM.render(<MyApp />, document.getElementById('root'));