React

自定义 hook —— useLocalStorageState

2021-09-07  本文已影响0人  Lia代码猪崽

基础功能

  1. state 保存到 localStorage 中,实现本地持久化;
  2. 如果清空了值,也从 localStorage 中删除这条数据;
  3. 会自动处理序列化和反序列化的操作;
  4. 重新刷新页面后也能拿到之前的值;
  5. 同源多页面之间也能共享值,当其中一个页面的值发生了改变,不刷新其他页面下也能更新值。

具体实现代码

import { useState, useEffect } from "react";

const useLocalStorageState = (key, defaultState) => {
  const [localState, setLocalState] = useState(defaultState);
  const [showState, setShowState] = useState(defaultState);

  // 刷新页面后能拿到值
  useEffect(() => {
    const value = localStorage.getItem(key);
    if (!value) {
      return;
    }
    setLocalState(value);
  // eslint-disable-next-line react-hooks/exhaustive-deps
  }, []);

  // 同源页面监听改变实时刷新
  useEffect(() => {
    const storageFuction = function(e) {
      const value = e.newValue
      setLocalState(value)
    }
    window.addEventListener('storage', storageFuction)
    return () => {
      window.removeEventListener('storage', storageFuction)
    }
    // console.log(localStorage.getItem(key))
  }, [])

  useEffect(() => {
    if (localState) {
      if (typeof localState === "object") {
        localStorage.setItem(key, JSON.stringify(localState));
      } else {
        localStorage.setItem(key, String(localState));
      }
      setShowState(localState)
      return;
    }
    localStorage.removeItem(key);
    setShowState(undefined)
  // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [localState]);

  return [showState, setLocalState];
};

export default useLocalStorageState;

demo

demo1

import useLocalStorageState from './hooks/useLocalStorageState'

function App() {
  const [state,setState] =  useLocalStorageState('test', [])
  return (
    <div className="App" style={{textAlign: 'center'}}>
      <header className="App-header">
        <p>
          { state }
        </p>
        <button onClick={() => setState([...state, 'A'])}>Push A</button>
        <button onClick={() => setState(state.slice(0, state.length - 1))}>Pop A</button>
      </header>
    </div>
  );
}

export default App;

demo2

import useLocalStorageState from './hooks/useLocalStorageState'

function App() {
  const [state,setState] =  useLocalStorageState('test', '')
  return (
    <div className="App" style={{textAlign: 'center'}}>
      <header className="App-header">
        <p>
          { state }
        </p>
        <input value={state || ''} onChange={(e) => setState(e.target.value)} />
      </header>
    </div>
  );
}

export default App;
上一篇 下一篇

猜你喜欢

热点阅读