这是一个小到甚至可以直接复制到你项目中用来代替useState 的项目
状态持久化 状态分离 存储在localStorage中
原理其实很简单 每个状态其实都是一个useState 只是做了些小改动
状态会有一个副本合集 存在一个js对象中 这个副本只是用来记录 不会导致组件更新
每一次setState 都是改变原有的useState中的数据
每一次读取 如果localStorage中有数据则返回localStorage中的数据 如果没有 则是从副本中读取
基于这一特性 每次父组件更新状态 子组件们都会重新读取localStorage的状态 所以甚至可以做一个局部的状态管理 但是不太推荐
const Count = ( ) => {
const [ count , setCount ] = useLocState ( 'count' , 0 )
return (
< div className = { styles . box1 } >
< div onClick = { e => { setCount ( count - 1 ) } } > -</ div >
< input
type = "number"
value = { count }
onChange = { e => {
setCount ( + e . target . value )
} } />
< div onClick = { e => { setCount ( count + 1 ) } } > +</ div >
</ div >
)
}
来看看设计前意料之外的局部状态管理(我承认这在某种方面算是一个bug 但是貌似提供了便利 所以就保留了下来)
功能依旧是数字加减 但是多了一个状态记录加减的操作记录 并且导入了一个子组件
const Count2 = ( ) => {
const [ count , setCount ] = useLocState ( 'count' , 0 )
const [ countlist , setCountList ] = useLocState < number [ ] > ( 'countlist' , [ ] )
return (
< >
< CountHistory />
< div className = { styles . box1 } >
< div onClick = { e => {
setCount ( count - 1 )
setCountList ( [ ...countlist , count ] )
} } > -</ div >
< input
type = "number"
value = { count }
onChange = { e => {
setCount ( + e . target . value )
} } />
< div onClick = { e => {
setCount ( count + 1 )
setCountList ( [ ...countlist , count ] )
} } > +</ div >
</ div >
</ >
)
//子组件不接受任何props 只是读取localStorage中的数据
const CountHistory = ( ) => {
const countlist :number [ ] = useLocValue ( "countlist" ) ;
const ref :any = useRef ( null ) ;
useEffect ( ( ) => {
ref . current . scrollTop = ref . current . scrollHeight ;
} )
return (
< div ref = { ref } className = { styles . box2 } >
{
countlist ?. map ( ( item , index ) => {
return (
< div key = { index } > { item } </ div >
)
} )
}
</ div >
)
}
因为加减操作是父组件进行的 所以每次更新状态都会导致自组件读取本地数据 从而更新页面
所以如果父祖件没有进行更新 uselocValue(key:string) 只会运行一次 所以不要想用本库当全局状态管理 他本身只是一个持久化状态的 useState
另外通过useLocState解构的setState在useLocState1.0.4版本之后才能像useState中的setState一样传入函数
还暴露了一个本地数据的接口clearLocValue 仅仅只是调用了一localStorage.removeItem("locState") 不会清除其他参数放心使用
需要注意的是删除本地数据 状态不会发生改变 需要手动更改状态 逻辑如下
uselocState(key,value) => const value = localStorage.getItem(key) ?? value => 副本更新参数(key:value) => localStorage.setitem('locstate',副本)
[state,setState] = useState(value) //调用React 原生hook
setLocState(newState) => 副本更新参数(key,newState) => localStorage.set('locstate',副本) => setState(newState) 设置state时 副本先更新数据 然后存储本地 最后设置状态
clearLocValue => localStorage.removeItem("locState") 未涉及状态