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

React Router基于ProtectedRoute按角色跳转时页面白屏问题求助

核心问题排查

你遇到的白屏问题是以下3个原因共同导致的:

  • Route的render函数是同步执行的,你在内部调用异步的getProfile请求时,render函数不会等待异步返回结果就直接执行结束,没有返回任何可渲染的内容,所以直接展示白屏
  • 你在then回调中返回的<Layout />/<AdminLayout />既没有被return到render函数的作用域,也没有触发组件重新渲染,就算请求成功了也不会显示
  • 没有添加加载状态和角色不匹配的兜底逻辑,请求过程中、权限校验失败时没有对应的渲染内容

修复方案

修改protectedRoute.js代码如下即可解决问题:

import React, {useState, useEffect} from 'react';
import {Route, Redirect} from 'react-router-dom';
import Layout from './layouts/layout';
import AdminLayout from './layouts/adminLayout';
import {useDispatch, useSelector} from 'react-redux';
import {getProfile} from './data_actions/userInfo_action/userInfo_action';
import {unwrapResult} from '@reduxjs/toolkit';

export const ProtectedRoute = ({admin = false, ...rest}) => {
  const dispatch = useDispatch();
  // 从redux取已缓存的用户信息,避免每次路由切换重复请求
  const userInfo = useSelector(state => state.userInfo);
  const [loading, setLoading] = useState(!userInfo?.role);
  const [authError, setAuthError] = useState(false);

  useEffect(() => {
    // 已经有用户角色则跳过请求
    if (userInfo?.role) {
      setLoading(false);
      return;
    }
    dispatch(getProfile())
      .then(unwrapResult)
      .catch(err => {
        setAuthError(true);
        setLoading(false);
      });
  }, [dispatch, userInfo]);

  // 加载状态可替换为你自己的加载组件
  if (loading) return <div>加载中...</div>

  // 鉴权失败跳转到登录页
  if (authError) {
    return <Redirect
      to={{
        pathname: '/fn/sign/login',
        state: {
          from: rest.location,
        },
      }}
    />
  }

  // 角色权限校验
  const isAdmin = userInfo.role === 'ADMIN';
  // 普通用户访问管理页跳转404
  if (admin && !isAdmin) return <Redirect to="/404" />
  // 管理员访问普通用户页自动跳转到后台
  if (!admin && isAdmin) return <Redirect to="/admin" />

  // 校验通过返回对应布局
  return (
    <Route
      {...rest}
      render={(props) => admin ? <AdminLayout {...props} /> : <Layout {...props} />}
    />
  );
};

额外优化建议

  • 你原来的ProtectedRoute接收了component参数但未使用,当前修复代码是直接根据admin参数返回对应布局,你可以按需调整为使用传入的component渲染
  • 建议在getProfile的redux逻辑里把返回的用户信息存入userInfo状态,避免每次路由切换重复请求接口
  • 如果你需要访问根路径自动跳转到普通用户首页,可以在router.js中添加重定向规则:
<Route exact path={`${process.env.PUBLIC_URL}`} render={() => <Redirect to="/joblist" />} />

内容的提问来源于stack exchange,提问作者Ga Yeon Kim

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 11:48:01