likes
comments
collection
share

使用 React hook 实现 remember me 功能

作者站长头像
站长
· 阅读数 4

相信大家在使用 React 写页面的时候都遇到过完成 Remember me 的需求吧!本文就将这个需求封装在一个 React hook 中以供后续的使用,觉得有用的同学可以收藏起来以备不时之需。

1. useRememberMe 钩子函数

在 React 中实现这个功能,其本质无非就是持久化存储。一般遇到这种问题,我都是用 hook 来解决的,因为 hook 可以将很多可以复用的逻辑封装起来,所以使用 hook 处理复杂逻辑非常合适。

使用 React hook 实现 remember me 功能 下面是完整的 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. 原理解释

  1. 自定义Hook useRememberMe:

    • useRememberMe 是一个自定义Hook,用于处理"remember me"的功能。
    • 它接收两个参数:initialUsername(默认用户名)和initialRemember(是否默认记住我),都有默认值。
    • 使用useState定义了三个状态:username(用户名)、remember(是否选择记住我)、isRemembered(用户名是否被记住)。
    • 第一个 useEffect 在组件挂载时从 localStorage 中恢复用户名和 "remember me" 的状态。
    • 第二个 useEffect 根据 remember 的状态来存储或删除 localStorage 中的用户名和 "remember me" 的状态。
    • 返回一个对象,包含状态和操作这些状态的方法,供组件使用。
  2. React函数组件 LoginForm:

    • 使用useRememberMe Hook,并解构其返回的对象,获取状态和更新状态的方法。
    • 定义了handleSubmit函数处理表单提交,目前仅阻止默认行为。
    • 返回JSX描述的UI,包括用户名输入框、密码输入框、"Remember me"复选框和提交按钮。
      • 用户名输入框的值与username状态绑定,输入变化时更新username
      • "Remember me"复选框的状态与remember绑定,选择变化时更新remember
  3. 组件的渲染:

    • 最后,通过<LoginForm />来渲染这个登录表单组件。在实际应用中,这一步通常会在一个父组件或路由中完成。

4. 最终效果

<LoginForm /> 组件渲染到页面上之后的效果如下所示:

使用 React hook 实现 remember me 功能

点击登录按钮之前的效果: 使用 React hook 实现 remember me 功能

登录之后刷新页面后的效果: 使用 React hook 实现 remember me 功能