reactjs React.js动态路由刷新后得到空白页

a2mppw5e  于 2023-02-04  发布在  React
关注(0)|答案(2)|浏览(169)

我在我的项目中实现了动态路由,根据用户角色打开不同的页面。https://github.com/javaLuo/react-admin
它在初始加载页面时工作正常。但是,每当我尝试刷新BasicLayout中的任何页面而不是login page时,它都会返回空白页面。
index.js:

import React, { useEffect, useState } from "react";
import { Navigate, BrowserRouter, Routes, Route, Outlet, Router } from 'react-router-dom';
import { createHashHistory as createHistory} from "history";
import { connect} from "react-redux";
import tools from "../util/tools";
import BasicLayout from "../layouts/BasicLayout";
import UserLayout from "../layouts/UserLayout";

const history = createHistory();
    
const RouterContainer = (props) => {
  useEffect(() => {
    const userinfo = localStorage.getItem("userinfo");
    if(userinfo){
      props.setUserInfo(JSON.parse(userinfo));
    }
  },[]);

  const onEnter = (Component, props) => {
    const userinfo = localStorage.getItem("userinfo");
    if (userinfo) {
      return <Component {...props} />;
    }
    return <Navigate to="/public/login"/>;
  };

  return (
    <BrowserRouter history={history}>
      <Routes>
        <Route path="/public/*" element={<UserLayout />} />
        <Route path="/*" element={onEnter(BasicLayout, props)}/> 
      </Routes>
    </BrowserRouter>
  );
};

export default connect(
  (state) => ({
    userinfo: state.app.userinfo,
  }),
  (dispatch) => ({
    setUserInfo: dispatch.app.setUserInfo,
  })
)(RouterContainer);

如果localeStorage中没有登录记录,则onEnter函数将重定向到登录页面。
BasicLayout.js

import React, { useState } from "react";
import { connect } from "react-redux";
import { Route, Routes, Navigate, useLocation, useNavigate } from "react-router-dom";
import Loadable from "react-loadable";
import tools from "../util/tools";
import { Layout, message } from "antd";
//... reduced to prevent too much code

// Router
const [NotFound, NoPower, Home,AlertNdr, MenuAdmin, PowerAdmin, RoleAdmin, UserAdmin] = [
  () => import(`../views/error/404`),
  () => import(`../views/error/401`),
  () => import(`../views/Home`),
  () => import(`../views/analytic/AlertNdr`),
  () => import(`../views/sys/MenuAdmin`),
  () => import(`../views/sys/PowerAdmin`),
  () => import(`../views/sys/RoleAdmin`),
  () => import(`../views/sys/UserAdmin`),
].map((item) => {
  return Loadable({
    loader: item,
    loading: Loading,
  });
});

const { Content } = Layout;

const BasicLayout = (props) => {
  const [collapsed, setCollapsed] = useState(false);
  const location = useLocation();
  const onToggle = () => setCollapsed(!collapsed);
  let history = useNavigate();
  const onLogout = () => {
    props.onLogout().then(() => {
      message.success("退出成功");
      history.push("/");
    });
  };
  
  const checkRouterPower = (pathname) => {
    let menus;
    console.log(pathname)
    if (props.userinfo.menu.rows && props.userinfo.menu.rows.length) {
      menus = props.userinfo.menu.rows;
    } else if (localStorage.getItem("userinfo")) {
      menus = JSON.parse(localStorage.getItem("userinfo")).menu.rows;
    }
    const m = menus.map((item) => item.url.replace(/^\//, ""));
    const urls = pathname.split("/").filter((item) => !!item);
    for (let i = 0; i < urls.length; i++) {
      if (!m.includes(urls[i])) {
        return false;
      }
    }
    return true;
  };
  
  const onEnter = (Component, props) =>{
    if(checkRouterPower(location.pathname)){
      console.log("test");
      return <Component {...props} />
    }
    return <Navigate to="/nopower" />
  };
  
  return (
    <Layout className="page-basic">
       <Menu
          data={props.userinfo.menu.rows}
          collapsed={collapsed}
          location={props.location}
          history={history}
        />
      <Layout>
        <Header
            collapsed={collapsed}
            userinfo={props.userinfo}
            onToggle={onToggle}
            onLogout={onLogout}
        />
        <Content className="content">
          <Routes>
            <Route path="/" element={<Navigate to="/home" />}/>
            <Route path="/home" element={onEnter(Home, props)}/>
            <Route path="/analytic/alertNdr" element={onEnter(AlertNdr, props)}/>
            <Route path="/system/menuadmin" element={onEnter(MenuAdmin, props)}/>
            <Route path="/system/poweradmin" element={onEnter(PowerAdmin, props)}/>
            <Route path="/system/roleadmin" element={onEnter(RoleAdmin, props)} />
            <Route path="/nopower" element={<NoPower/>} />
            <Route path="*" element={<NotFound/>} />
          </Routes>
        </Content>
      </Layout>
    </Layout>
  );
  };

export default connect(
  (state) => ({
    userinfo: state.app.userinfo,
  }),
  (dispatch) => ({
    onLogout: dispatch.app.onLogout,
  })
)(BasicLayout);
a64a0gku

a64a0gku1#

尝试在您的index.js中将useEffect更改为useMemo

useMemo(() => {
const setUserInfo = async (parsedUserinfo) => {
  await props.setUserInfo(parsedUserinfo);
}

const userinfo = localStorage.getItem("userinfo");
if(userinfo){
  const parsedUserinfo = JSON.parse(userinfo);
  setUserInfo(parsedUserinfo)
}
},[]);
wydwbb8l

wydwbb8l2#

element是可选的,它可以是React.ReactNodenull
试试这个。

const OnEnter = ({ children }) => {
    const userinfo = localStorage.getItem("userinfo");
    if (userinfo) {
      return <>{children}</>
    }
    return <Navigate to="/public/login"/>;
  };

  return (
    <BrowserRouter history={history}>
      <Routes>
        <Route path="/public/*" element={<UserLayout />} />
        <Route path="/*" element={<Onter><BasicLayout {...props}</OnEnter>}/> 
      </Routes>
    </BrowserRouter>
  );

还必须更改BasicLayout中的所有onEnter

相关问题