Javascript React.js:如何在呈现页面之前先运行useEffect?

Javascript React.js:如何在呈现页面之前先运行useEffect?,javascript,reactjs,ecmascript-6,Javascript,Reactjs,Ecmascript 6,我试图实现一个动态菜单,它根据用户角色改变其结构 请参阅下面的完整代码: import React, { useState, useLayoutEffect, useEffect, useCallback, } from "react"; import { Drawer, IconButton, List, Avatar } from "@material-ui/core"; import { Inbox as InboxIcon,

我试图实现一个动态菜单,它根据用户角色改变其结构

请参阅下面的完整代码:

import React, {
  useState,
  useLayoutEffect,
  useEffect,
  useCallback,
} from "react";
import { Drawer, IconButton, List, Avatar } from "@material-ui/core";
import {
  Inbox as InboxIcon,
  PresentToAll as PresentToAllIcon,
  ListAlt as ListAltIcon,
  Language as LanguageIcon,
  Description as DescriptionIcon,
  List as ListIcon,
  Money as MoneyIcon,
  Face as FaceIcon,
  TransferWithinAStation as TransferWithinAStationIcon,
  AttachMoney as AttachMoneyIcon,
  PersonPinCircle as PersonPinCircleIcon,
  Home as HomeIcon,
  ArrowBack as ArrowBackIcon,
  Edit as EditIcon,
  AccountBalanceWallet,
  PeopleAlt,
} from "@material-ui/icons";
import { useTheme } from "@material-ui/styles";
import { withRouter } from "react-router-dom";
import classNames from "classnames";
import useStyles from "./styles";
import SidebarLink from "./components/SidebarLink/SidebarLink";
import {
  useLayoutState,
  useLayoutDispatch,
  toggleSidebar,
} from "../../context/LayoutContext";
import Dot from "./components/Dot";
import pesonetlogo from "../../images/test-logo.png";
import { USER_PROFILE_ID_SESSION_ATTRIBUTE } from "../../services/AuthenticationService";
import ProfileMaintenanceService from "../../services/ProfileMaintenanceService";

function Sidebar({ location }) {
  var classes = useStyles();
  var theme = useTheme();

  var { isSidebarOpened, modules } = useLayoutState();
  var layoutDispatch = useLayoutDispatch();

  var [isPermanent, setPermanent] = useState(true);

  // should be in UserContext for global state
  const [profileDetails, setProfileDetails] = useState([]);
  const [profileModules, setProfileModules] = useState([]);
  // const [profileActions, setProfileActions] = useState([]);

  var structureNew = [];

  const profileList = sessionStorage.getItem(USER_PROFILE_ID_SESSION_ATTRIBUTE);

  useEffect(() => {
    modules.forEach((modulesMap, i) => {
      structureNew[i] = structure.filter(
        (structureFiltered) => structureFiltered.label == modulesMap
      );
    });
    console.log("06262020 useEffect structureNew ", structureNew)
  }, []);

  // useLayoutEffect(() => {
  //   console.log("06252020 useEffect profileDetails ", profileDetails);
  //   const modules = profileDetails.map((module) => module.module);
  //   // const actions = profileDetails
  //   //   .map((item) => item.actions.map((action) => action.action))
  //   //   .flat();
  //   setProfileModules(profileModules.concat(modules));
  //   // setProfileActions(profileActions.concat(actions));
  // }, [profileDetails]);

  // useLayoutEffect(() => {
  //   console.log("06252020 useEffect profileModules ", profileModules);
  //   structureNew = structure.filter(
  //     (structureFiltered) => structureFiltered.label == "Inward"
  //   );
  //   console.log("06252020 structureNew ", structureNew);
  // }, [profileModules]);

  // // // should be in UserContext for global use
  // const retrieveProfileDetails = useCallback(() => {
  //   const profileListArr = profileList.split(",");
  //   profileListArr.forEach((profileListArrMap) => {
  //     ProfileMaintenanceService.retrieveProfileDetails(profileListArrMap).then(
  //       // dapat makuha din menu?
  //       (response) => {
  //         console.log(
  //           "06252020 retrieveProfileDetails response.data ",
  //           response.data
  //         );
  //         setProfileDetails(response.data);
  //       }
  //     );
  //   });
  // });

  var structure = [
    { id: 0, label: "Dashboard", link: "/test/dashboard", icon: <HomeIcon /> },
    {
      id: 1,
      label: "Test1",
      link: "/test1",
      icon: <InboxIcon />,
    },
    {
      id: 2,
      label: "Test2",
      link: "/test2",
      icon: <PresentToAllIcon />,
    },
    { id: 3, type: "divider" },
    {
      id: 4,
      label: "Test3",
      link: "/test3",
      icon: <ListAltIcon />,
      children: [
        {
          label: "Test4",
          link: "/test4",
          icon: <LanguageIcon />,
        },
        {
          label: "Test5",
          link: "/test5",
          icon: <ListIcon />,
        },
      ],
    },
    {
      id: 5,
      label: "Test6",
      link: "/test6",
      icon: <DescriptionIcon />,
    },
    {
      id: 6,
      label: "Test7",
      link: "/test7",
      icon: <AccountBalanceWallet />,
      children: [
        {
          label: "Test8",
          link: "/test8",
          icon: <FaceIcon />,
        },
        {
          label: "Test9",
          link: "/test9",
          icon: <TransferWithinAStationIcon />,
        },
        {
          label: "Test10",
          link: "/test10",
          icon: (
            <Avatar alt="Pesonet" src={pesonetlogo} className={classes.small} />
          ),
        },
        {
          label: "Test11",
          link: "/test11",
          icon: <PeopleAlt />,
        },
      ],
    },
    {
      id: 7,
      label: "Test12",
      link: "/test12",
      icon: <EditIcon />,
    },
  ];

  useEffect(function() {
    window.addEventListener("resize", handleWindowWidthChange);
    handleWindowWidthChange();
    return function cleanup() {
      window.removeEventListener("resize", handleWindowWidthChange);
    };
  });

  return (
    <Drawer
      variant={isPermanent ? "permanent" : "temporary"}
      className={classNames(classes.drawer, {
        [classes.drawerOpen]: isSidebarOpened,
        [classes.drawerClose]: !isSidebarOpened,
      })}
      classes={{
        paper: classNames({
          [classes.drawerOpen]: isSidebarOpened,
          [classes.drawerClose]: !isSidebarOpened,
        }),
      }}
      open={isSidebarOpened}
    >
      <div className={classes.toolbar} />
      <div className={classes.mobileBackButton}>
        <IconButton onClick={() => toggleSidebar(layoutDispatch)}>
          <ArrowBackIcon
            classes={{
              root: classNames(classes.headerIcon, classes.headerIconCollapse),
            }}
          />
        </IconButton>
      </div>
      <List className={classes.sidebarList}>
        {structureNew.map((link) => (
          <SidebarLink
            key={link.id}
            location={location}
            isSidebarOpened={isSidebarOpened}
            {...link}
          />
        ))}
      </List>
    </Drawer>
  );

  function handleWindowWidthChange() {
    var windowWidth = window.innerWidth;
    var breakpointWidth = theme.breakpoints.values.md;
    var isSmallScreen = windowWidth < breakpointWidth;

    if (isSmallScreen && isPermanent) {
      setPermanent(false);
    } else if (!isSmallScreen && !isPermanent) {
      setPermanent(true);
    }
  }
}

export default withRouter(Sidebar);
import-React{
useState,
使用布局效果,
使用效果,
使用回调,
}从“反应”;
从“@material ui/core”导入{Drawer,IconButton,List,Avatar};
进口{
收件箱为Inboxion,
作为对Allicon的陈述,
ListAlt作为ListAltIcon,
作为语言图标的语言,
描述如描述一样,
作为列表图标列出,
金钱是金钱的象征,
Face作为FaceIcon,
转让,作为转让,
作为附件的附件,
人形圈作为人形圈,
Home作为HomeIcon,
ArrowBack作为ArrowBack图标,
编辑为编辑图标,
账户余额钱包,
人们,
}从“@材料界面/图标”;
从“@material ui/styles”导入{useTheme}”;
从“react router dom”导入{withRouter};
从“类名”中导入类名;
从“/styles”导入useStyles;
从“/components/SidebarLink/SidebarLink”导入SidebarLink;
进口{
使用LayoutState,
使用LayoutDispatch,
切换侧边栏,
}来自“../../context/LayoutContext”;
从“/components/Dot”导入点;
从“../../images/test logo.png”导入PesoneLogo;
从“./../services/AuthenticationService”导入{USER_PROFILE_ID_SESSION_ATTRIBUTE};
从“../../services/ProfileMaintenanceService”导入ProfileMaintenanceService;
函数侧栏({location}){
var class=useStyles();
var-theme=useTheme();
var{issidebarped,modules}=useLayoutState();
var layoutDispatch=useLayoutDispatch();
var[isPermanent,setPermanent]=useState(真);
//应在全局状态的UserContext中
const[profileDetails,setProfileDetails]=useState([]);
const[profileModules,setProfileModules]=useState([]);
//const[profileActions,setProfileActions]=useState([]);
var structureNew=[];
const profileList=sessionStorage.getItem(用户配置文件\u ID\u会话\u属性);
useffect(()=>{
modules.forEach((modulemap,i)=>{
structureNew[i]=structure.filter(
(structureFiltered)=>structureFiltered.label==模块映射
);
});
日志(“06262020 Useffect structureNew”,structureNew)
}, []);
//useLayoutEffect(()=>{
//日志(“06252020 Useffect profileDetails”,profileDetails);
//const modules=profileDetails.map((module)=>module.module);
////const actions=profileDetails
////.map((项目)=>item.actions.map((操作)=>action.action))
////。平坦();
//setProfileModules(profileModules.concat(modules));
////setProfileActions(profileActions.concat(actions));
//}[profileDetails]);
//useLayoutEffect(()=>{
//日志(“06252020 Useffect profileModules”,profileModules);
//structureNew=structure.filter(
//(structureFiltered)=>structureFiltered.label==“向内”
//   );
//console.log(“06252020 structureNew”,structureNew);
//},[profileModules]);
/////应在UserContext中供全局使用
//const retrieveProfileDetails=useCallback(()=>{
//const profileListArr=profileList.split(“,”);
//profileListArr.forEach((profileListArrMap)=>{
//ProfileMaintenanceService.retrieveProfileDetails(profileListArrMap)。然后(
////dapat makuha din菜单?
//(回应)=>{
//console.log(
//“06252020 retrieveProfileDetails response.data”,
//答复.数据
//         );
//setProfileDetails(response.data);
//       }
//     );
//   });
// });
变量结构=[
{id:0,标签:“仪表板”,链接:“/test/Dashboard”,图标:},
{
id:1,
标签:“Test1”,
链接:“/test1”,
图标:,
},
{
id:2,
标签:“Test2”,
链接:“/test2”,
图标:,
},
{id:3,键入:“分隔符”},
{
id:4,
标签:“Test3”,
链接:“/test3”,
图标:,
儿童:[
{
标签:“Test4”,
链接:“/test4”,
图标:,
},
{
标签:“Test5”,
链接:“/test5”,
图标:,
},
],
},
{
id:5,
标签:“Test6”,
链接:“/test6”,
图标:,
},
{
id:6,
标签:“Test7”,
链接:“/test7”,
图标:,
儿童:[
{
标签:“Test8”,
链接:“/test8”,
图标:,
},
{
标签:“Test9”,
链接:“/test9”,
图标:,
},
{
标签:“Test10”,
链接:“/test10”,
图标:(
),
},
{
标签:“Test11”,
链接:“/test11”,
图标:,
},
],
},
{
id:7,
标签:“Test12”,
链接:“/test12”,
图标:,
},
];
useffect(函数(){
addEventListener(“调整大小”,handleWindowWidthChange);
HandleIndowWidthChange();
返回函数cleanup(){
removeEventListener(“调整大小”,handleWindowWidthChange);
};
});
返回(
toggleSidebar(layoutDispatch)}>
{structureNew.map((链接)=>(
))}
);
函数handlewindwidthchange(){
var windowWidth=window.innerWidth;
var breakpointWidth=theme.breakpoints.values.md;
var isSmallScreen=窗宽<窗宽;
如果(isSmallScreen&&ISPERMANNT){
设置永久性(假);
}如果(!isSmallScreen&&!isPermanent)为else,则为{
setPermanent(真);
}
}
}
使用路由器导出默认值(侧栏);
如您所见,
structureNew
包含一些数组操作后在
useffect
中形成的菜单和子菜单

但是,我的问题是页面首先呈现,然后调用
structureNew
。此时,
structureNew
为空

const [loading, setLoading] = useState(true)
setLoading(false)
if(loading){
    return(<LoaderComponent/>)
}
return(
//your main return
)