ReactRouter基础

ReactRouter基础

react-router

本质上react-router有三个模块,react-router、react-router-dom、react-router-native

在React项目中,路由实现需要使用react-router-dom模块

react-router安装/使用

# npm
npm i --save react-router-dom

# yarn
yarn add react-router-dom

我们需要在我们的项目中引入react-router-dom

import {
    
     BrowserRouter as Router, Route, Switch, Link } from 'react-router-dom'

BrowserRouter/HashRouter

如果我们要使用路由,那么应该在App.js中用BrowserRouter包着所有的代码

前者路由url中不带#,后者带#

BrowserRouter基于HTML5的pushState操作,HashRouter基于hash操作

一个页面只会有一个Router

import {
    
     BrowserRouter as Router, Route, Switch, Link } from 'react-router-dom'
function App () {
    
    
  return (
    <div className="app">
      <Router>
      
      </Router>
    </div>
  )
}

Route

每一个路由都放在一个Route里

ute path="路由路径">
    <Component a={
    
    1}></Component>
  </Route>
  <!-- 第二种写法 -->
  <Route path="路由路径" component={
    
    组件}></Route>
  <!-- 第三种写法 -->
  <Route path="路由路径" render={
    
    (props) => <Component {
    
    ...props} a={
    
    1}></Component>}></Route>
</Router>

上面的三种方式区别在于组件内部的props的内容

function Page (props) {
    
    
  // 第一种方式 props中只能获取到我们添加到组件上的自定义属性
  // 第二种方式 props中包含了所有的路由信息 不包含自定义属性,也无法设置
  // 第三种方式 porps默认为空,可以添加自定义属性,如果想要有路由信息,需要我们设置对应props传递
  return (
    <div></div>
  )
}

exact
精确匹配,如果不添加该属性 path=“/” 也会匹配到 /xxx,可以给Route添加该属性

<Route exact></Route>

Switch
如果Route的path和url匹配,则对应的Route的组件就会渲染,Switch控制了Route只能渲染匹配到的第一个。

<Router>
  <Switch>
    <Route path="路由路径">
      <Component></Component>
    </Route>
    <!-- 第二种写法 -->
    <Route path="路由路径" component={
    
    组件}></Route>
    <!-- 第三种写法 -->
    <Route path="路由路径" render={
    
    () => <Component></Component>}></Route>
  </Switch>
</Router>

Link
会被渲染成a标签,和vue的router-link相同

<Link to="path">链接名称</Link>

NavLink

和Link的区别在于NavLink会根据当前URL匹配对应的a标签添加类名 active

<NavLink to="path">链接名称</NavLink>

路由配置

如果想要像vue一样实现路由的配置,我们可以自己写配置,并根据配置渲染出对应的路由结构

安装 react-router-dom

npm install react-router-dom -S
// 或者
yarn add react-router-dom 

配置好routes

const routes = [
  // 同级重定向
  {
    
    
    path: "/redirect",
    render: () => <Redirect to="/demo1"/>
  },
  {
    
    
    path: "/",
    exact: true,
    component: Index
  }, {
    
    
    path: "/demo1",
    component: Demo1,
    // 子路由配置
    routes: [
      {
    
    
        path: "/demo1/child1",
        component: Child1
      },
      // 重定向 父 -> 子
      {
    
    
        path: "/demo1",
        render: () => <Redirect to="/demo1/child1"/>
      }
    ]
  }
]

在App.js中添加函数

import {
    
     BrowserRouter as Router } from 'react-router-dom'
import {
    
     renderRoutes } from 'react-router-config'
import routes from '路由配置路径'
function App () {
    
    
  return (
    <div className="App">
      <Router>
        {
    
    renderRoutes(routes)}
      </Router>
    </div>
  )
}

找到有子路由的组件

import {
    
     renderRoutes } from 'react-router-config'
function 组件名 ({
     
     route}) {
    
    
  return (
    <div>
      {
    
    renderRoutes(route.routes)}
    </div>
  )
}

组件懒加载

组件的配置
组件需要放在lazy中调用

FuntionComponent.js

function FuctionComponent () {
    
    
  return (
    <div>组件</div>
  )
}
export default FunctionComponent

懒加载

import {
    
     Lazy } from 'react'
const FunctionComponent = Lazy(() => import('组件路径'))

把通过Lazy引入的组件放在对应的组件中

Suspense组件可以去包裹Lazy加载的组件,内部可以包裹多个

<Suspense fallback={
    
    <div>loading...</div>}>
  <Lazy组件></Lazy组件>
</Suspense>

在组件外使用路由导航功能

假如我们需要在组件外使用history进行路由导航。比如:在响应拦截器中遇到token失效跳转登录页的场景

安装模块react-router和history

yarn add react-router history

到App.js进行结构改造

App.sj

import './App.css';
// import { BrowserRouter as Router, Route, Switch, Redirect } from 'react-router-dom'
import {
    
     Route, Switch, Redirect} from 'react-router-dom'
// 从上一步安装的模块中,引入对应的Router
import {
    
     Router } from 'react-router'
// 引入创建history对象方法
import {
    
     createBrowserHistory } from 'history'

import Login from './views/Login';
import MainLayout from './views/Layout';
import NotFound from './views/NotFound';

// 创建history对象 并且导出 在需要进行导航的地方引入并调用方法即可
export const history = createBrowserHistory()

function App() {
    
    
  return (
    <div className="App">
      {
    
    /* 把创建的history对象添加到Router上 */}
      <Router history={
    
    history}>
        ...
      </Router>
    </div>
  );
}

export default App;

猜你喜欢

转载自blog.csdn.net/z18237613052/article/details/126058296