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

React使用Context判断登录状态为false时重定向否则允许访问页面的实现方法

第一步:修正Context默认值

你当前的Context默认值为布尔值false,但Provider实际传递的是包含loggedIn状态和toggleLoggedIn方法的对象,直接解构会报错,先修改Context.js:

import React from 'react';
// 匹配Provider传递的结构设置默认值
export const AppContext = React.createContext({
  loggedIn: false,
  toggleLoggedIn: () => {}
});

第二步:实现认证HOC

新建withAuthProtection.js文件,代码如下:

import React, { useContext } from 'react';
import { Redirect } from 'react-router-dom';
import { AppContext } from './context';

// 高阶组件:接收需要保护的组件作为参数,返回新组件
export const withAuthProtection = (WrappedComponent) => {
  const ProtectedComponent = (props) => {
    const { loggedIn } = useContext(AppContext);
    // 未登录直接重定向到登录页
    if (!loggedIn) {
      return <Redirect to="/login" />;
    }
    // 已登录则渲染原组件,透传所有props
    return <WrappedComponent {...props} />;
  };
  return ProtectedComponent;
};

第三步:使用HOC保护页面

有两种使用方式可选:

  • 方式1:在组件导出时包裹,以AlertsTable为例:
import { withAuthProtection } from './withAuthProtection';

function AlertsTable() {
  // 原有组件逻辑
}
// 导出时包裹HOC,该组件只要被渲染就会触发鉴权
export default withAuthProtection(AlertsTable);
  • 方式2:在路由定义时直接包裹,修改App.js中对应路由:
// 先导入HOC和需要保护的组件
import { withAuthProtection } from './withAuthProtection';
import AlertsTable from './AlertsTable';

// 路由处直接包裹
<Route path="/open_alerts/">
  <div className="alerts-table new-line-block">
    <br></br>
    {withAuthProtection(AlertsTable)()}
  </div>
</Route>

更适配React Router的优化方案:封装ProtectedRoute组件

相比通用HOC,专门封装路由级别的保护组件使用更便捷,不需要逐个修改组件导出:
新建ProtectedRoute.js:

import React, { useContext } from 'react';
import { Route, Redirect } from 'react-router-dom';
import { AppContext } from './context';

export const ProtectedRoute = (props) => {
  const { loggedIn } = useContext(AppContext);
  const { component: Component, ...rest } = props;
  return (
    <Route
      {...rest}
      render={(routeProps) => {
        if (loggedIn) {
          return <Component {...routeProps} />;
        }
        return <Redirect to="/login" />;
      }}
    />
  );
};

修改App.js中的路由配置,需要保护的路由直接用ProtectedRoute替换原Route即可:

// 导入ProtectedRoute
import { ProtectedRoute } from './ProtectedRoute';

<Switch>
  <Route exact path="/login/">
    <div>
      <LoginPage />
    </div>
  </Route>
  {/* 首页需要保护 */}
  <ProtectedRoute exact path="/">
    <div className="charts new-line-block">
      <div className="split left">
        <AlertsChart />
      </div>
      <div className="split right">
        <RegionCharts />
      </div>
    </div>
    <br></br>
    <br></br>
  </ProtectedRoute>
  {/* 告警页需要保护 */}
  <ProtectedRoute path="/open_alerts/">
    <div className="alerts-table new-line-block">
      <br></br>
      <AlertsTable />
    </div>
  </ProtectedRoute>
  {/* 其他需要保护的路由同理替换即可 */}
</Switch>

补充:登录成功后跳转

可以在登录成功后跳转到首页,修改Login.js的handleSubmit逻辑:

// 导入useHistory
import { useHistory } from 'react-router-dom';

export function LoginPage() {
  const { loggedIn, toggleLoggedIn } = useContext(AppContext);
  const history = useHistory();

  const handleSubmit = (event) => {
    fetch("/accounts/login", {
      method: 'POST',
      body: JSON.stringify({
        'username': user,
        'password': password
      })
    })
    .then((response) => {
      if(response.ok) {
        toggleLoggedIn(true);
        // 登录成功跳转到首页
        history.push('/');
      } else {
        // 错误处理逻辑
      }
    })
  }
  // 原有组件逻辑
}

内容的提问来源于stack exchange,提问作者xdgdeveloper

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 19:36:04