发布于 2026-01-06 0 阅读
0

在 React 中存储用户偏好设置

在 React 中存储用户偏好设置

本教程最初发布于此处。

允许用户选择偏好设置固然很好,但如果他们继续使用下去……

指的是用户偏好。用户留存则是完全不同的另一个话题。但就用户数据的保存而言,方法却出奇地简单直接。

注意安全

存储用户数据时,务必牢记安全问题。切勿将用户密码或密钥等信息保存在可能导致未经授权访问的位置。在本演示中,我们仅存储用户的主题偏好设置。

入门

上一篇教程中,我们学习了如何创建深色模式切换按钮:

src/App.js

import './App.css';
import { useEffect, useState } from 'react';

function App() {
  const [darkMode, setDarkMode] = useState(false);

  useEffect(() => {
    if (darkMode) {
      document.body.classList.add('dark');
    }
    else {
      document.body.classList.remove('dark');
    }
  }, [darkMode]);

  return (
    <div className="App">
      <h1>{darkMode ? 'Dark Mode' : 'Light Mode'}</h1>
      <p>This is a test</p>
      <button
        className="dark-mode-toggle"
        onClick={() => {
          setDarkMode(!darkMode);
        }}>
        <div className="dark-mode-slider" />
      </button>
    </div>
  );
}

export default App;

Enter fullscreen mode Exit fullscreen mode

src/App.css


* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}
.App {
  height: 100vh;
  width: auto;
  text-align: center;
  font-size: 5em;
  color: #2e3440;
  background-color: #d8dee9;
  transition: all 0.2s ease;
}
.dark,
.dark .App {
  color: #d8dee9;
  background-color: #2e3440;
  transition: all 0.2s ease;
}

/* Button Styles */

.dark-mode-toggle {
  width: 80px;
  height: 36px;
  border-radius: 50px;
  top: 0;
  left: 0;
}
.dark-mode-toggle svg {
  fill: #000;
}
.dark-mode-slider {
  height: 30px;
  width: 30px;
  border-radius: 50%;
  background-color: #2e3440;
  display: flex;
  position: relative;
  transform: translateX(0px);
  transition: all 0.2s ease;
}

.dark .dark-mode-slider {
  transform: translateX(45px);
}

Enter fullscreen mode Exit fullscreen mode

它去哪儿了?

让我们仔细看看我们的功能。点击按钮后,样式会在浅色模式和深色模式之间切换,太棒了!如果您切换到深色模式并刷新页面,可能会发现页面又自动切换回了浅色模式,因为这是我们的默认设置。

使其粘住

让我们通过使用localStorage API来存储我们的偏好设置,从而解决这个问题。

我们需要更新一下useEffect钩子函数:


  useEffect(() => {
    if (darkMode) {
      document.body.classList.add('dark');
    }
    else {
      document.body.classList.remove('dark');
    }
  }, [darkMode]);

Enter fullscreen mode Exit fullscreen mode

致以下人员:


useEffect(() => {
    if (darkMode) {
      localStorage.setItem('prefersDarkMode', 'true');
      document.body.classList.add('dark');
    }
    else {
      localStorage.setItem('prefersDarkMode', 'false');
      document.body.classList.remove('dark');
    }
  }, [darkMode]);

Enter fullscreen mode Exit fullscreen mode

在这个改动中,我们指示应用程序将键值对存储到浏览器中,但您可能已经注意到,我们只是设置了该项,并没有用它来控制状态。为了实现这一点,我们需要在useEffect刚刚编辑的钩子上方添加另一个钩子,它应该如下所示:


  useEffect(() => {
    const storedPreference = localStorage.getItem('darkModePreference');
    if (storedPreference) {
      setDarkMode(JSON.parse(storedPreference));
    }
  }, []);

Enter fullscreen mode Exit fullscreen mode

让我们仔细看看。我们使用该getItem方法检索之前设置的键的值,并使用该JSON.parse方法将字符串值转换为布尔值。
我们将依赖项数组留空,因为我们只想让它在应用程序首次挂载时运行。完成此更改后,我们现在可以刷新页面,主题首选项会自动加载,而无需切换按钮。

节省一些时间

在某些情况下,用户设备上可能已经预设了一些偏好设置,我们可以利用这些设置来构建初始状态。例如,我们可以使用matchMedia API来检查用户设备是否设置了主题偏好。为此,我们可以修改之前的useEffect钩子,使其如下所示:


    useEffect(() => {
        const storedPreference = localStorage.getItem('darkModePreference');
        if (storedPreference) {
        setDarkMode(JSON.parse(storedPreference));
        }
        else {
        const prefersDarkMode = window.matchMedia('(prefers-color-scheme: dark)').matches;
        setDarkMode(prefersDarkMode);
        }
    }, []);

Enter fullscreen mode Exit fullscreen mode

我们使用一条if语句来检查用户是否在其设备上设置了偏​​好设置。如果设置了,我们将状态设置为该偏好设置的值。如果没有设置,我们将使用matchMediaAPI 检查用户是否偏好深色模式。如果偏好,我们将使用prefers-color-scheme: dark媒体查询将状态设置为深色模式。这将返回一个布尔值,我们将状态设置prefersDarkMode为该值。这将触发我们的初始useEffect钩子运行,并更新我们的应用程序以匹配用户的偏好设置。

这就是在浏览器中持久化数据所需的全部步骤。这只是一个简单的示例,但许多开发者发现这种方法非常有用,可以用来存储大量非敏感数据,而无需向服务器发出昂贵的请求,此外还有许多其他创造性的用途。

文章来源:https://dev.to/lrth06/storing-user-preferences-in-react-2g4i