react-router实现类似vue-router中befor

2021-05-23  本文已影响0人  _stan
react-router中并没有vue-router的路由导航守卫(如beforeEach)等api。
具体原因,作者已经在github上做出了回答

意思是您可以在渲染功能中执行此操作。JSX不需要API,因为它更灵活。

在react中可以使用高阶组件hoc在渲染route组件之前判断登录状态
App.tsx
import React from 'react'
import { BrowserRouter as Router, Route, Switch, Link } from 'react-router-dom'
import { AuthButton, PrivateRoute } from './components'
import RootProvider from './RootProvider'
import { Home, Login, User } from './pages'

const App: React.FC = () => {
  return (
    <RootProvider>
      <Router>
        <AuthButton />
        <ul>
          <li><Link to="/home">home</Link></li>
          <li><Link to="/user">user</Link></li>
        </ul>
        <Switch>
          <PrivateRoute path={'/home'}>
            <Home />
          </PrivateRoute>
          <PrivateRoute path={'/user'}>
            <User />
          </PrivateRoute>
          <Route path={'/login'} component={Login} />
        </Switch>
      </Router>
    </RootProvider>
  )
}

export default App

PrivateRoute是一个高阶组件,主要作用是判断登录状态,如果没有登录则跳转到登录页面。
PrivateRoute.tsx
import React from 'react'
import { useAuth } from '../../RootProvider'
import { Route, Redirect, RouteProps } from 'react-router-dom'

export const PrivateRoute: React.FC<RouteProps> = ({ children, ...props }) => {
  const { user } = useAuth()
  return (
    <Route
      {...props}
      render={({ location }) =>
        user ? (
          children
        ) : (
          <Redirect
            to={{
              pathname: '/login',
              state: { from: location }
            }}
          />
        )
      }
    />
  )
}
全局的context
import React, { createContext, Context, useContext } from 'react'
import { useLogin } from './hooks'

const AuthContext: Context<any> = createContext({})

const RootProvider: React.FC = ({ children }) => {
  const auth = useLogin()
    
  return (
    <AuthContext.Provider value={auth}>
      {children}
    </AuthContext.Provider>
  )
}

export const useAuth = () => useContext(AuthContext)

export default RootProvider
 
使用到的hook
import { useState } from 'react'

export const useLogin = () => {
  const [user, setUser] = useState<string | null>(null)

  const login = cb => {
    setUser('lin')
    cb()
  }

  const logout = cb => {
    setUser(null)
    cb()
  }

  return {
    user,
    login,
    logout
  }
}

最后的效果:

上一篇下一篇

猜你喜欢

热点阅读