最简单的自定义钩子来持久化数据。

2025-06-09

最简单的自定义钩子来持久化数据。

我最近在填写一份基于Typeform(强烈推荐使用)的调查问卷,不得不说,与 Google Form、Microsoft Form 等竞争对手相比,它的用户体验非常出色。最让我着迷的是,即使我不小心在中间关闭了该标签页并重新打开,之前填写的所有信息仍然保留。与 Google Form 或我遇到的其他平台不同,Typeform 会持久保存数据。

Typeform 之前利用的是浏览器的本地存储 API。所以,作为一个 React 开发者,我非常想做一个 React Hook,以便在未来的项目中使用,充分利用本地存储的优势。

自定义钩子useLocalState

在这里我们将使用window.localStorageAPI 并将数据存储在浏览器的本地存储中。即使您关闭标签页并返回同一页面,之前的状态也会被保留。

为此,首先我们将使用一个useState带有回调函数的钩子,如果数据存在,则从浏览器的本地存储返回值,否则,将默认值作为 prop 传递。

const [value, setValue] = useState(() => {
    const tempValue = window.localStorage.getItem(key);
    return tempValue !== null ? JSON.stringify(tempValue) : defaultVal;
});
Enter fullscreen mode Exit fullscreen mode

数据可以保存到本地存储,并为数据分配特定的键。你也可以将其视为一种对象。

接下来,我们需要同步数据,并在数据发生变化时进行更新。我们将使用useEffect钩子来实现这一点。

useEffect(() => {
    window.localStorage.setItem(key, JSON.stringify(value));
}, [value]);
Enter fullscreen mode Exit fullscreen mode

自定义useLocalStorage钩子。

import { useEffect, useState } from "react";

const useLocalStorage = (defaultVal, key) => {
  const [value, setValue] = useState(() => {
    const tempValue = window.localStorage.getItem(key);
    return tempValue !== null ? JSON.stringify(tempValue) : defaultVal;
  });

  useEffect(() => {
    window.localStorage.setItem(key, JSON.stringify(value));
  }, [value]);

  return [value, setValue];
};

export default useLocalStorage;
Enter fullscreen mode Exit fullscreen mode

示例应用程序

让我们制作一个具有两个函数(增量和减量)的简单计数器来理解这个概念。

import React from "react";

const App = () => {
  const [count, setCount] = useLocalState(0, "count");

  const increment = () => {
    setCount(count + 1);
  };

  const decrement = () => {
    setCount(count - 1);
  };

  return (
    <div>
      <h1>Counter:</h1>
      <h2>{count}</h2>
      <button onClick={increment}>Increment (+)</button>
      <button onClick={decrement}>Decrement (-)</button>
    </div>
  );
};

export default App;
Enter fullscreen mode Exit fullscreen mode

尝试一下这个例子。

笔记

请勿在 SSR 框架中使用此钩子。本地存储 API 在 SSR 框架(例如 Nextjs、Gatsby 等)中会显示错误。因为它将在服务器端编译,并且将引用服务器的本地存储,而不是客户端浏览器的本地存储。

鏂囩珷鏉ユ簮锛�https://dev.to/imrishabh18/simplest-custom-hook-to-persist-data-1odd
PREV
Flask 与 Django 对比?
NEXT
创建一个 Next.js Markdown 博客。图片