手动实现react-router路由拦截

其实这个话题在网上找已经能找到很多解决方案了,之所以写这篇文章主要也是让自己对路由拦截加深点印象吧(毕竟自己没实现过路由拦截。。。)。用vue时已经有导航守卫,在公司里做项目路由拦截的部分也早已经写好,那就只能自己做demo练习一下了。react-router本身没提供导航守卫,按作者的说法是可以自己来实现,那就自己来实现一下吧。

我在上家公司用的是react-router4,现在已经有react-router6可以使用了,我们先使用react-router4写一遍再来使用react-router6,会使用一个再来使用另一个也不难了,现在先定义最简单的需求:

  1. 定义三个页面,登录页,首页,关于我们页面
  2. 登录页和关于我们是免登录页面。要进入首页必须状态认证通过,否则会跳转到登录页

react-router4:

xml 复制代码
<HashRouter>
  <Switch>
    <Route exact path="/" component={Home} />
    <Route exact path="/aboutUs" component={AboutUs} />
    <Route exact path="/login" component={Login} />
  </Switch>
</HashRouter>

定义好路由后,通过修改地址栏,就能匹配路径渲染相应的组件。所以要做路由拦截,我们可以选择不要直接渲染Route组件,可以自定义AuthRoute组件,组件最终会返回Route组件,在返回Route组件之前我们就可以判断状态不通过时跳转登录页的操作,从而实现路由拦截。

方法一:自定义权限组件

  1. 自定义AuthRoute组件,AuthRoute组件会返回Route组件
  2. AuthRoute返回Route之前进行状态认证,不通过会跳转到登录页
javascript 复制代码
<HashRouter>
  <Switch>
    <AuthRoute exact path="/" component={Home} />
    <Route exact path="/aboutUs" component={AboutUs} />
    <Route exact path="/login" component={Login} />
  </Switch>
</HashRouter>
    
const AuthRoute = (props) => {
    const auth = null

    if (!auth) {
        alert('跳转到登录页')
        return <Redirect to="/login" />
    }

    return (
        <Route {...props} />
    )
}

效果:

方法二:使用Route自带的render属性

xml 复制代码
<HashRouter>
  <Switch>
    <Route exact path="/" render={() => auth ? <Home /> : <Redirect to="/login" /> } />
    <Route exact path="/aboutUs" component={AboutUs} />
    <Route exact path="/login" component={Login} />
  </Switch>
</HashRouter>

这种方法也可以通过判断状态来渲染不同的组件,认证不通过则跳转到登录页。但是需要路由拦截的页面可能会有很多个,而且需要认证的状态也可能不止一个,所以最好还是封装一个自定义组件来实现。

react-router6:

我们先试下同样使用自定义组件来进行路由拦截。

xml 复制代码
<HashRouter>
    <Routes>
      <AuthRoute exact path="/" element={<Home />} />
      <Route exact path="/login" element={<Login />}></Route>
      <Route exact path="/aboutUs" element={<AboutUs />}></Route>
    </Routes>
</HashRouter>

效果:

结果报了错,在Routes组件里只能是Route组件不能是自定义组件,所以稍微改造一下,Routes里只放Route组件,把自定义组件放到element属性上。

自定义权限组件

javascript 复制代码
const AuthRoute = (props) => {
    const auth = null

    if (!auth) {
        return <Navigate to="login" />
    }

    return props.component
}

<Routes>
  <Route exact path="/" element={<AuthRoute component={<Home />} />} />
  ...
</Routes>

效果:

现在路由拦截完成了,不过Route组件可以嵌套,所以可以在优化下Route的写法,外层Route是自定义组件,内层Route是页面组件,这样代码更清晰

javascript 复制代码
AuthRoute组件:
import { Navigate, Outlet } from 'react-router-dom'

const AuthRoute = (props) => {
    const auth = null

    if (!auth) {
        return <Navigate to="login" />
    }

    return <Outlet />
}
export default AuthRoute


<HashRouter>
    <Routes>
      <Route path="/" element={<AuthRoute />}>
        <Route path='/' element={<Home/>}/>
      </Route>
      <Route path="/login" element={<Login />}></Route>
    </Routes>
</HashRouter>

其中Outlet组件就是内层的Route组件,这样就可以把所有需要状态认证的路由都放到内层的Route组件。

总结:react-router4和react-router6的路由拦截大同小异,主要核心是在返回页面组件前先进行一些状态判断,根据判断的结果来进行路由跳转,从而实现路由拦截。

相关推荐
溪语流沙10 分钟前
【Web全栈进阶】PostgreSQL上手:Docker跑库 + 把早报站从SQLite迁过去
前端·docker·postgresql
IT_陈寒16 分钟前
SpringBoot自动配置的坑:你以为的捷径可能是弯路
前端·人工智能·后端
paopaokaka_luck16 分钟前
高校社团管理(AI辅助任务分配、协同过滤算法推荐、ECharts数据可视化、活动参与闭环、校园交流与反馈、器材借还管理)
java·前端·javascript·spring boot·数据分析·echarts
5008432 分钟前
React Native for OpenHarmony 实战:三方库 react-native-volume-control 的鸿蒙化适配指南
javascript·react native·react.js·electron·harmonyos
薛一半36 分钟前
React-Redux三重优化实战揭秘
javascript·vue.js·react.js
Dovis(誓平步青云)40 分钟前
导览音频切换太快,旧讲解不能覆盖新展品
android·前端·javascript·ecmascript·音视频·宠物
福兮说11 小时前
设计稿是 #4A7C6F,页面量出来是 #4B7C6F:HEX、HSL、透明度、canvas 来回转的七个坑
前端·javascript·css·canvas
郑州光合科技余经理12 小时前
海外版外卖加盟:总站与分站配送规则怎么分开管
java·开发语言·前端·后端·uni-app·php·ai编程
小呆呆66613 小时前
副业搞起来,小说,漫画,漫剧的成本优化思路
前端·后端·面试
Dovis(誓平步青云)13 小时前
浇水提醒刚弹出又消失,植物状态别只存一个百分比
开发语言·前端·javascript·pdf·ecmascript·电脑