在 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;
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);
}
它去哪儿了?
让我们仔细看看我们的功能。点击按钮后,样式会在浅色模式和深色模式之间切换,太棒了!如果您切换到深色模式并刷新页面,可能会发现页面又自动切换回了浅色模式,因为这是我们的默认设置。
使其粘住
让我们通过使用localStorage API来存储我们的偏好设置,从而解决这个问题。
我们需要更新一下useEffect钩子函数:
useEffect(() => {
if (darkMode) {
document.body.classList.add('dark');
}
else {
document.body.classList.remove('dark');
}
}, [darkMode]);
致以下人员:
useEffect(() => {
if (darkMode) {
localStorage.setItem('prefersDarkMode', 'true');
document.body.classList.add('dark');
}
else {
localStorage.setItem('prefersDarkMode', 'false');
document.body.classList.remove('dark');
}
}, [darkMode]);
在这个改动中,我们指示应用程序将键值对存储到浏览器中,但您可能已经注意到,我们只是设置了该项,并没有用它来控制状态。为了实现这一点,我们需要在useEffect刚刚编辑的钩子上方添加另一个钩子,它应该如下所示:
useEffect(() => {
const storedPreference = localStorage.getItem('darkModePreference');
if (storedPreference) {
setDarkMode(JSON.parse(storedPreference));
}
}, []);
让我们仔细看看。我们使用该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);
}
}, []);
我们使用一条if语句来检查用户是否在其设备上设置了偏好设置。如果设置了,我们将状态设置为该偏好设置的值。如果没有设置,我们将使用matchMediaAPI 检查用户是否偏好深色模式。如果偏好,我们将使用prefers-color-scheme: dark媒体查询将状态设置为深色模式。这将返回一个布尔值,我们将状态设置prefersDarkMode为该值。这将触发我们的初始useEffect钩子运行,并更新我们的应用程序以匹配用户的偏好设置。
这就是在浏览器中持久化数据所需的全部步骤。这只是一个简单的示例,但许多开发者发现这种方法非常有用,可以用来存储大量非敏感数据,而无需向服务器发出昂贵的请求,此外还有许多其他创造性的用途。
文章来源:https://dev.to/lrth06/storing-user-preferences-in-react-2g4i