实现一个自定义 React Hook:useLocalStorageState

简介: 大家好,我是前端西瓜哥。最近做需求,需要将数据保存到 localStorage 里,在组件初始化的时候获取,然后修改该值的时候,要保存到本地的 localStorage 中。

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

最近做需求,需要将数据保存到 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

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

相关文章
|
11月前
|
人工智能 自然语言处理 前端开发
SpringBoot + 通义千问 + 自定义React组件:支持EventStream数据解析的技术实践
【10月更文挑战第7天】在现代Web开发中,集成多种技术栈以实现复杂的功能需求已成为常态。本文将详细介绍如何使用SpringBoot作为后端框架,结合阿里巴巴的通义千问(一个强大的自然语言处理服务),并通过自定义React组件来支持服务器发送事件(SSE, Server-Sent Events)的EventStream数据解析。这一组合不仅能够实现高效的实时通信,还能利用AI技术提升用户体验。
776 2
|
6月前
|
编解码 前端开发 开发者
React 图片组件样式自定义:常见问题与解决方案
在 React 开发中,图片组件的样式自定义常因细节问题导致布局错乱、性能损耗或交互异常。本文系统梳理常见问题及解决方案,涵盖基础样式应用、响应式设计、加载状态与性能优化等,结合代码案例帮助开发者高效实现图片组件的样式控制。重点解决图片尺寸不匹配、边框阴影不一致、移动端显示模糊、加载失败处理及懒加载等问题,并总结易错点和最佳实践,助力开发者提升开发效率和用户体验。
205 22
|
6月前
|
Web App开发 移动开发 前端开发
React 视频播放器样式自定义实战指南
本文详细介绍了如何在React项目中实现视频播放器的样式自定义,涵盖HTML5 `&lt;video&gt;`标签的基础知识、CSS样式定制技巧及常见问题解决方案。针对全屏模式样式失效、移动端触摸事件冲突和进度条样式定制等问题提供了具体代码示例。同时,探讨了视频预加载策略和内存优化方法,并推荐了几款调试工具,帮助开发者提升用户体验和应用性能。
194 6
|
6月前
|
Web App开发 移动开发 前端开发
React音频播放器样式自定义全解析:从入门到避坑指南
在React中使用HTML5原生&lt;audio&gt;标签时,开发者常面临视觉一致性缺失、样式定制局限和交互体验割裂等问题。通过隐藏原生控件并构建自定义UI层,可以实现完全可控的播放器视觉风格,避免状态不同步等典型问题。结合事件监听、进度条拖拽、浏览器兼容性处理及性能优化技巧,可构建高性能、可维护的音频组件,满足跨平台需求。建议优先使用成熟音频库(如react-player),仅在深度定制需求时采用原生方案。
221 12
|
设计模式 存储 前端开发
React开发设计模式及原则概念问题之自定义Hooks的作用是什么,自定义Hooks设计时要遵循什么原则呢
React开发设计模式及原则概念问题之自定义Hooks的作用是什么,自定义Hooks设计时要遵循什么原则呢
|
前端开发
React给antd中TreeSelect组件左侧加自定义图标icon
本文介绍了如何在React中为Ant Design的TreeSelect组件的每个树节点添加自定义图标,并解决了因缺少key属性而导致的警告问题,展示了如何通过递归函数处理treeData数据并为每个节点添加图标。
628 2
React给antd中TreeSelect组件左侧加自定义图标icon
|
前端开发 Python
React技术栈-React路由插件之自定义组件标签
关于React技术栈中React路由插件自定义组件标签的教程。
171 4
React技术栈-React路由插件之自定义组件标签
|
11月前
|
前端开发 JavaScript API
自定义React Hooks综合指南
本文介绍了React Hooks及其在组件开发中的作用,重点讲解了自定义Hook的创建和使用方法。通过实例展示了如何创建`useWindowWidth`、`useFetch`和`useForm`等自定义Hook,并分享了使用自定义Hook的最佳实践。文章强调了自定义Hook在提高代码复用性和组件可维护性方面的重要性。
244 0
|
前端开发 JavaScript
|
前端开发
React 中的 Hook 概念
【8月更文挑战第31天】
207 0