You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.27 21:58:20