React JS中基于角色的菜单无法自动渲染,需手动刷新如何解决?
解决React角色菜单动态渲染不生效的问题
问题核心:当前代码在模块加载时就一次性读取了localStorage中的角色,之后角色变化时不会重新计算菜单内容——因为模块级别的代码只会执行一次,不会自动刷新。
解决方案:将菜单转为React组件,动态监听角色变化
把原来的静态导出改成函数组件,利用React的状态和副作用钩子监听角色变化,自动更新菜单:
import { useState, useEffect } from 'react'; import { ReactSession } from 'react-client-session'; import dashboard from './dashboard'; import dashboard1 from './dashboard1'; import dashboard2 from './dashboard2'; import companies from './companies'; import investors from './investors'; import incubators from './incubators'; ReactSession.setStoreType("localStorage"); export default function RoleBasedMenu() { const [menuItems, setMenuItems] = useState({ items: [] }); // 计算对应角色的菜单 const calculateMenu = () => { const role = ReactSession.get("role"); let newMenu; if (role == 3) { newMenu = { items: [dashboard1, companies] }; } else if (role == 2) { newMenu = { items: [dashboard, incubators] }; } else if (role == 4) { newMenu = { items: [dashboard2, investors] }; } else { newMenu = { items: [] }; // 默认空菜单 } setMenuItems(newMenu); }; // 组件挂载时初始化菜单,同时监听localStorage变化 useEffect(() => { calculateMenu(); // 监听同源页面的storage变化 const handleStorageChange = (e) => { if (e.key === "role") { calculateMenu(); } }; window.addEventListener('storage', handleStorageChange); // 监听当前页面的localStorage修改(可选,解决当前页修改不触发storage事件的问题) const originalSetItem = localStorage.setItem; localStorage.setItem = function(key, value) { originalSetItem.apply(this, arguments); if (key === "role") { calculateMenu(); } }; // 清理监听事件 return () => { window.removeEventListener('storage', handleStorageChange); localStorage.setItem = originalSetItem; }; }, []); return menuItems; }
额外优化:抽离角色管理自定义Hook
把角色监听逻辑抽成独立Hook,方便在其他组件复用:
import { useState, useEffect } from 'react'; import { ReactSession } from 'react-client-session'; ReactSession.setStoreType("localStorage"); export function useRole() { const [role, setRole] = useState(ReactSession.get("role")); useEffect(() => { // 跨页面storage监听 const handleStorageChange = (e) => { if (e.key === "role") { setRole(ReactSession.get("role")); } }; window.addEventListener('storage', handleStorageChange); // 当前页面localStorage修改监听 const originalSetItem = localStorage.setItem; localStorage.setItem = function(key, value) { originalSetItem.apply(this, arguments); if (key === "role") { setRole(value); } }; return () => { window.removeEventListener('storage', handleStorageChange); localStorage.setItem = originalSetItem; }; }, []); return role; }
之后在菜单组件中使用这个Hook,代码更简洁:
import { useState, useEffect } from 'react'; import { useRole } from './useRole'; // ...导入菜单项 export default function RoleBasedMenu() { const role = useRole(); const [menuItems, setMenuItems] = useState({ items: [] }); useEffect(() => { let newMenu; if (role == 3) { newMenu = { items: [dashboard1, companies] }; } else if (role == 2) { newMenu = { items: [dashboard, incubators] }; } else if (role == 4) { newMenu = { items: [dashboard2, investors] }; } else { newMenu = { items: [] }; } setMenuItems(newMenu); }, [role]); // 角色变化时自动更新菜单 return menuItems; }
这样只要角色值发生变化,菜单就会自动重新渲染,无需手动刷新页面。
内容的提问来源于stack exchange,提问作者Selva Simon p
相关产品推荐
相关产品推荐

