【React】单页面应用限制多开登录

react 单页面应用限制多开登录

情景

测试小姐姐提了一个 BUG : 在同一浏览器中打开两个页面,两个页面分别登录不同的账号.A 页面先登录A, B 页面再登录B,此时回到 A 页面,交互时账号数据应该刷新为 B 登录的账号

分析

这个问题,其实没什么必要,因为我不认为我们这个系统的单个使用者会同时拥有多个账号,但人家非说会有,那行吧,我说了不算,还是考虑解决问题吧。

React 也是 SPA 应用,在一个页面中变更数据并不会直接影响到另一个页面,所以我们得让我们的应用与某些全局共享的东西保持同步,比如站点在浏览器中的本地存储。欸,这不就来了嘛,用户登录的数据(token,基础信息等)我们往往会通过 localStorage 持久化存储在浏览器中,只需要监听存储在 localStorage 的用户数据变化即可同步我们的页面。

方案

  1. 在一个全局存在的组件中(如 Header,或者干脆 RootApp 等),监听 storage
  2. 绑定监听 storage 触发的函数,获取 localStorage 中的 userInfo(假设我们把登录成功后的用户数据全存在 userInfo 字段)
  3. 如果 userInfo 存在,更新 react 应用的状态中共享的用户数据,并强制刷新页面
  4. 如果 userInfo 没了,清空 react 应用的状态中共享的用户数据,并强制退出登录

伪代码

userManage.ts: 一些存取变更 localStorage 用户数据的封装

ts 复制代码
export default {
  state,
  login,  // 这个就是 localStorage.setItem("userInfo", val)
  logout, // 这个就是 localStorage.clear(); 和 window.location 重定向到登录页
  getUserInfo, // 这个就是尝试 localStorage.getItem("userInfo") 并反序列化
};

某个全局组件:

ts 复制代码
useEffect(() => {
  /** 监听 localStorage 的 userInfo 变化并同步 */
  async function syncUser() {
    const userInfo = localStorage.getItem('userInfo');
      if (userInfo) {
        userManage.login(JSON.parse(userInfo));
        window.location.reload();
      } else {
      	userManage.logout();
      }
    }
    window.addEventListener('storage', syncUser);
    return () => {
      window.removeEventListener('storage', syncUser);
    };
}, []);

这样就基本实现了多开限制,Bingo!

相关推荐
qq_246100052 小时前
CSDN risk probe 1773588273
开发语言·javascript·ecmascript
ByteCraze3 小时前
Vue 递归组件实战:手写一个文件/文件夹树形组件
javascript·vue.js·ecmascript
前端Hardy3 小时前
前端如何防止用户重复提交表单?4 种可靠方案(附防坑指南)
前端·javascript·面试
前端Hardy3 小时前
用户真的关掉页面了吗?前端精准检测页面卸载的 4 种方法(附避坑指南)
前端·javascript·面试
yangyanping201083 小时前
Vue入门到精通七之关键字const
前端·javascript·vue.js
姝然_95273 小时前
Jetpack Compose 绘制流程与自定义布局
前端
lxh01133 小时前
重复的DNA序列
开发语言·javascript·ecmascript
姝然_95273 小时前
Jetpack Compose Brush 渐变
前端
阿鑫_9963 小时前
通用-ESLint+Prettier基础知识
前端·后端
ai超级个体3 小时前
金三银四,一个面试官连连夸赞的个人网页技术分享
前端·面试·three.js·threejs·网页设计·网页灵感·网页分享