为编程爱好者分享易语言教程源码的资源网
好用的代理IP,游戏必备 ____广告位招租____ 服务器99/年 ____广告位招租____ ____广告位招租____ 挂机,建站服务器
好用的代理IP,游戏必备 ____广告位招租____ 服务器低至38/年 ____广告位招租____ ____广告位招租____ 挂机,建站服务器

网站首页 > 网络编程 正文

实现一个自定义 React Hook:useLocalStorageState

三叶资源网 2022-09-30 20:18:50 网络编程 294 ℃ 0 评论

大家好,我是前端西瓜哥。

最近做需求,需要将数据保存到 localStorage 里,在组件初始化的时候获取,然后修改该值的时候,要保存到本地的 localStorage 中。

倒是并不难。

function App() {
  const STORAGE_NAME = 'app_theme';
  const defaultVal = '前端西瓜哥'
  const [value, setValue] = useState(() => {
    const storage = localStorage.getItem(STORAGE_NAME);
    return storage || defaultVal;
  })
  
  const changeValue = (val) => {
    localStorage.setItem(STORAGE_NAME, val);
    setValue(val);
  }
  return (
    <div>
      <input value={value} onChange={e => changeValue(e.target.value)}/>
    </div>
  );
}

很显然,这些逻辑完全可以封装为一个 React Hook,名字很容易想到为 useLocalStorageState。

const useLocalStorageState = (key, defaultValue) => {
  const data = localStorage.getItem(key);
  const [value, setValue] = useState(data || defaultValue);
  return [
    value,
    (val) => {
      localStorage.setItem(key, val);
      setValue(val);
    }
  ];
};

逻辑并不复杂。就是在读和写的时候,加上 localStorage 的读写逻辑就好了。

用法如下:

function App() {
  const STORAGE_NAME = "app_theme";
  const defaultVal = "前端西瓜哥";
  const [value, setValue] = useLocalStorageState(STORAGE_NAME, defaultVal);
  return (
    <div>
      <input value={value} onChange={e => setValue(e.target.value)} />
    </div>
  );
}

其实这个实现还是比较粗糙的,只支持字符串格式,如果你要保存对象,需要自己手动 JSON.parse 和 JSON.stringify 来扩展了数据类型的范围。

我们可以加一下序列化和反序列化支持:

const useLocalStorageState = (key, defaultValue) => {
  const data = localStorage.getItem(key);
  const [value, setValue] = useState(JSON.parse(data || defaultValue));
  return [
    value,
    (val) => {
      localStorage.setItem(key, JSON.stringify(val));
      setValue(val);
    }
  ];
};
// 使用
function App() {
  const STORAGE_NAME = "app_theme";
  const defaultVal = { name: "前端西瓜哥" };
  const [value, setValue] = useLocalStorageState(STORAGE_NAME, defaultVal);
  return (
    <div>
      <input
        value={value.name}
        onChange={(e) => setValue({ name: e.target.value })}
      />
    </div>
  );
}

另外,JSON 序列化和反序列方法如果不够用,我们可以再加个自定义序列反序列化方法:

const useLocalStorageState = (key, defaultValue, serializer, deserializer) => {
  defaultValue = localStorage.getItem(key) || defaultValue;
  const [value, setValue] = useState(
    deserializer ? deserializer(defaultValue) : JSON.parse(defaultValue)
  );
  return [
    value,
    (val) => {
      localStorage.setItem(
        key,
        serializer ? serializer(val) : JSON.stringify(val)
      );
      setValue(val);
    }
  ];
};

其实优秀的第三方 React Hook 库 ahooks 也有这个实现,我还是建议大家用一些比较成熟的轮子,我这里只是提供一下思路。

ahooks 的 useLocalStorageState 的源码:

https://github.com/alibaba/hooks/blob/v3.4.0/packages/hooks/src/useLocalStorageState/index.ts

我是前端西瓜哥,喜欢写前端技术文章,欢迎关注我。

Tags:

来源:三叶资源网,欢迎分享,公众号:iisanye,(三叶资源网⑤群:21414575

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

百度站内搜索
关注微信公众号
三叶资源网⑤群:三叶资源网⑤群

网站分类
随机tag
高级记事本折线图仿QQ音乐播放器百度网盘跳一跳辅助源码群排名动画源码高级表格支持库字库验证码识别文件夹加密sign算法源码钓鱼薅羊毛视频教程网页分析工具超级列表框背景透明关键词采集精易模块网页填表多线程采集
最新评论