我的个人博客

将React组件状态与本地存储同步

Published on
Published on
/2 mins read/---

一个简单的自定义Hook,用于将组件状态与本地存储同步。

use-local-storage-state.ts
import { useState, useEffect } from 'react'
 
export function useLocalStorageState<T = { [key: string]: any }>(key: string, defaultValue?: T) {
  let [state, setState] = useState<T>(() => {
    let storage = localStorage.getItem(key)
    if (storage) {
      return JSON.parse(storage)
    }
    return defaultValue || {}
  })
 
  useEffect(() => {
    localStorage.setItem(key, JSON.stringify(state))
  }, [state])
 
  // Using `as const` to ensure the type of the returned array is correct
  return [state, setState] as const
}

在某些情况下,你可能需要检查浏览器环境,因为本地存储只在客户端可用。

use-local-storage-state.ts
import { useState, useEffect } from 'react'
 
let isBrowser = typeof window !== 'undefined' // 检查浏览器/客户端环境
 
export function useLocalStorageState<T = { [key: string]: any }>(key: string, defaultValue?: T) {
  let [state, setState] = useState<T>(() => {
    if (isBrowser) {
      let storage = localStorage.getItem(key)
      if (storage) {
        return JSON.parse(storage)
      }
    }
    return defaultValue || {}
  })
 
  useEffect(() => {
    localStorage.setItem(key, JSON.stringify(state))
  }, [state])
 
  return [state, setState] as const
}

使用方法

下面展示了使用该Hook将组件状态与本地存储同步的简单示例:

theme-switcher.tsx
function ThemeSwitcher() {
  let [theme, setTheme] = useLocalStorageState<'dark' | 'light'>('theme', 'light')
 
  return (
    <select onChange={ev => setTheme(ev.target.value)}>
      <option value="dark">Dark</option>
      <option value="light">Light</option>
    </select>
  )
}