使用 React hook 实现 remember me 功能
相信大家在使用 React 写页面的时候都遇到过完成 Remember me 的需求吧!本文就将这个需求封装在一个 React hook 中以供后续的使用,觉得有用的同学可以收藏起来以备不时之需。
1. useRememberMe 钩子函数
在 React 中实现这个功能,其本质无非就是持久化存储。一般遇到这种问题,我都是用 hook 来解决的,因为 hook 可以将很多可以复用的逻辑封装起来,所以使用 hook 处理复杂逻辑非常合适。
下面是完整的 hook 代码。
// 定义一个自定义Hook,用于处理"remember me"的功能
const useRememberMe = (initialUsername = '', initialRemember = false) => {
// 使用React的useState Hook来定义三个状态变量:
// username: 用于存储用户名
// remember: 用于标记用户是否选择了"remember me"选项
// isRemembered: 用于标记用户名是否被记住(从localStorage中恢复)
const [username, setUsername] = useState(initialUsername);
const [remember, setRemember] = useState(initialRemember);
const [isRemembered, setIsRemembered] = useState(false);
// 使用React的useEffect Hook,在组件挂载时执行(仅执行一次)
useEffect(() => {
// 从localStorage中尝试获取存储的用户名和"remember me"的状态
const storedUsername = localStorage.getItem('username');
const storedRemember = localStorage.getItem('remember');
// 如果用户名存在且"remember me"被选中,则恢复这些状态
if (storedUsername && storedRemember === 'true') {
setUsername(storedUsername);
setRemember(true);
setIsRemembered(true);
}
}, []); // 空的依赖数组表示这个effect只会在组件挂载时运行一次
// 另一个useEffect Hook,当remember或username状态变化时执行
useEffect(() => {
// 如果用户选择了"remember me",则将用户名和状态保存到localStorage中
if (remember) {
localStorage.setItem('username', username);
localStorage.setItem('remember', 'true');
} else {
// 否则,从localStorage中移除这些信息
localStorage.removeItem('username');
localStorage.removeItem('remember');
}
}, [remember, username]); // 当remember或username变化时,这个effect会重新运行
// 返回一个对象,包含所有的状态变量和更新状态的方法,供组件使用
return {
username,
setUsername,
remember,
setRemember,
isRemembered,
};
};
2. 小试牛刀
下面通过一个简单的例子来说明这个 hook 的用法:
// 定义一个React函数组件,用于显示登录表单
const LoginForm = () => {
// 使用上面定义的useRememberMe Hook,并解构返回的对象,获取状态和更新状态的方法
const {
username,
setUsername,
remember,
setRemember,
isRemembered,
} = useRememberMe();
// 定义一个处理表单提交的函数,目前仅阻止默认行为(即页面刷新),具体的登录逻辑需要在这里实现
const handleSubmit = (e) => {
e.preventDefault();
// 处理登录逻辑...
};
// 返回JSX,描述组件的UI
return (
<form onSubmit={handleSubmit}>
{/* 用户名输入框,值与username状态绑定,当输入变化时更新username状态 */}
<input
type="text"
placeholder="Username"
value={username}
onChange={(e) => setUsername(e.target.value)}
/>
{/* 密码输入框,目前没有绑定任何状态或处理逻辑 */}
<input
type="password"
placeholder="Password"
// 你需要添加密码状态和处理逻辑
/>
{/* "Remember me"复选框,状态与remember绑定,当选择变化时更新remember状态 */}
<label>
<input
type="checkbox"
checked={remember}
onChange={(e) => setRemember(e.target.checked)}
/>
Remember me
</label>
{/* 提交按钮 */}
<button type="submit">Login</button>
</form>
);
};
// 在React应用中渲染LoginForm组件
// 注意:在实际应用中,你通常会在一个父组件或路由中渲染这个组件,而不是直接这样写
<LoginForm />
3. 原理解释
-
自定义Hook
useRememberMe
:- useRememberMe 是一个自定义Hook,用于处理"remember me"的功能。
- 它接收两个参数:
initialUsername
(默认用户名)和initialRemember
(是否默认记住我),都有默认值。 - 使用
useState
定义了三个状态:username
(用户名)、remember
(是否选择记住我)、isRemembered
(用户名是否被记住)。 - 第一个
useEffect
在组件挂载时从localStorage
中恢复用户名和 "remember me" 的状态。 - 第二个
useEffect
根据remember
的状态来存储或删除localStorage
中的用户名和 "remember me" 的状态。 - 返回一个对象,包含状态和操作这些状态的方法,供组件使用。
-
React函数组件
LoginForm
:- 使用
useRememberMe
Hook,并解构其返回的对象,获取状态和更新状态的方法。 - 定义了
handleSubmit
函数处理表单提交,目前仅阻止默认行为。 - 返回JSX描述的UI,包括用户名输入框、密码输入框、"Remember me"复选框和提交按钮。
- 用户名输入框的值与
username
状态绑定,输入变化时更新username
。 - "Remember me"复选框的状态与
remember
绑定,选择变化时更新remember
。
- 用户名输入框的值与
- 使用
-
组件的渲染:
- 最后,通过
<LoginForm />
来渲染这个登录表单组件。在实际应用中,这一步通常会在一个父组件或路由中完成。
- 最后,通过
4. 最终效果
将 <LoginForm />
组件渲染到页面上之后的效果如下所示:
点击登录按钮之前的效果:
登录之后刷新页面后的效果:
转载自:https://juejin.cn/post/7360663978648059919