08- React路由 V6

240 阅读2分钟

一、基本使用

1、安装

yarn add react-router-dom

2、导入路由的三个核心组件:Router/Route/Link/Routes

import {BrowserRouter as Router, Route, Link, Routes} from "react-router-dom"

3、使用Router组件 包裹整个应用

  • 不需要加exact 精准匹配
  • 需要用Routes包裹起来 。routers:只会匹配一个
// 导入组件
import { Route, Routes} from "react-router-dom"

const First = () => <p> 页面一的内容 </p>

const App = () => {
  // 使用Router组件包裹整个应用
  <Router>
  	<Routes>
    	<h1>React路由基础</h1>
      {/* 指定路由入口 */}
      <link to="/first">页面一</link>
      {/* 指定路由出口 */}
      <Route path="first" element={First} />
    </Routes>
  </Router>
}

二、路由嵌套

  1. 当匹配到父级组件时会自动渲染index属性的组件
  2. outlet: 父路由元素中使用<Outlet>来渲染其子路由元素。这允许在呈现子路由时显示嵌套UI。
// 导入组件
import { Route, Routes} from "react-router-dom"

const First = () => <p> 页面一的内容 </p>

const LayoutRoot = () => {
  
  return <div class="Layout">
  					<Outlet />
  			 </div>
}

const App = () => {
  // 使用Router组件包裹整个应用
  <Router>
  	<Routes>
    	<Route path="/" element={<LayoutRoot />}>
        <Route index element={<Home />}</Route>
         {/* 会默认继承父级的path '/' */}
         <Route path="bar" element={<Home />}</Route> 
      </Route>
      <Route path="first" element={<First />} />
    </Routes>
  </Router>
}

三、编程式跳转

1、普通跳转

// 导入组件
import {BrowserRouter as Router, Route, Link} from "react-router-dom"
import { useNavigate, useParams } from "react-router-dom";
const Home = () => <p> 页面一的内容 </p>
// 函数组件路由跳转
const Login = () => {
  const loginHandle = ()=>{
	  // 使用编程式导航实现路由跳转
 	 	useNavigate('/home')
	}
  
  render() {
    return (
    	<div>
      	<p>登录页面:</p>
        <button onClick={this.handleLogin}></button>
      </div>
    )
  }
}
const App = () => {
  // 使用Router组件包裹整个应用
  <Router>
  	<Routes>
    	<h1>React路由基础</h1>
     	<Login></Login>
      <Route path="/Home" element={<Home />} />
    </Routes>
  </Router>
} 
ReactDOM.render(<App />,document.getElementByID('root'))

2、动态路由

创建

const App = () => {
  // 使用Router组件包裹整个应用
  <Router>
  	<Routes>
    	<h1>React路由基础</h1>
      <Route path="/Detail/:id" element={<Detail />} />
    </Routes>
  </Router>
} 

使用

// 导入组件
import {BrowserRouter as Router, Route, Link} from "react-router-dom"
import { useNavigate, useParams } from "react-router-dom";

// 发送数据 编程式
const Home = () => {
  const goAbout = () => {
    useNavigate('/About/1')
  }
  
  return (
    <div>
      <button onClick={goAbout}>动态路由</button>
    </div>
)
// 发送数据 声明式
 <Link to={`/about/1`}>Child2</Link>

// 接收数据
function Detail = () => {
  const BlogList = {
    1: {
      title:"第一篇文章",
      description: "关于Vue  3.0v的"
    },
    2: {
      title:"第二篇文章",
      description: "关于React 18.0.0v的"
    }
  }
  const { id } = useParams();
  const {title,description} =BlogList[id]
  
  return  (
  		<div>
  				<h2>{ title }</h2>
      		<h2>{ description }</h2>
  		</div>
  )
}

3、查询参数跳转

发送

// 发送参数 声明式
 <Link className="nav" to={`/bar?page=3&size=10&usename=list`}>Child2</Link>

// 发送数据 编程式
const Home = () => {
  const goBar = () => {
    useNavigate('/bar?page=3&size=10&usename=list')
  }
  
  return (
    <div>
      <button onClick={goBar}>查询参数</button>
    </div>
)

接收

// 导入组件
import {BrowserRouter as Router, Route, Link} from "react-router-dom"
import { useSearchParams } from "react-router-dom";
// 带参数详情组件
function Bar = () => {
  const [searchParams,setSearchParams] = useSearchParams()
  console.log(searchParams.get('page'))       // '3'
  console.log(searchParams.get('pageSize'))   // '10'
  console.log(searchParams.getAll('usename')) // [ 'list' ]
  return <div>Bar组件</div>
}
const App = () => {
  // 使用Router组件包裹整个应用
  <Router>
  	<Routes>
    	<h1>React路由基础</h1>
      <Route path="/Bar" element={<Bar />} />
    </Routes>
  </Router>
} 
ReactDOM.render(<App />,document.getElementByID('root'))

4、state参数

发送

//路由传参 声明式
 <Link
     className="nav"
     to={`/Detail`}
     state={{name:'tom',age:"20"}} 
 >
    Child2
</Link>

// 发送数据 编程式
const Home = () => {
  const goDetail = () => {
    useNavigate('/Detail', { state: {name:'tom',age:"20"} })
  }
  
  return (
    <div>
      <button onClick={goDetail}>state参数</button>
    </div>
)

接收

import { useLocation } from "react-router-dom";

const Detail = () => {
  const { name, age } = useLocation()

  return (
    <div>{name}</div>
    <div>{age}</div>
  )
}
 
export default Detail

四、配置路由规则

router/index.js

import { lazy } from "react"
// 导入组件
import { Route, Routes} from "react-router-dom"
// import Bar form "./view/Bar";
const Bar = lazy(() => import('./view/Bar'))
// import Home form "./view/Home";
const Home = lazy(() => import('./view/Home'))

// 这个layout不要懒加载  有闪屏
import LayoutRoot form "./view/LayoutRoot";

const lazyLoad =(children) => {
  return <Suspense fallback={<span>loading</span>}>{children}</Suspense>
}

const router = [
  {
    path: '/',
    element: <LayoutRoot />,
    children: [
      {
        index: true,
        element: lazyLoad(<Home />)
      },
      {
        path:"bar",
        element: lazyLoad(<Bar />)
      }
    ]
  }
]

export default router

App.js

import { Suspense } from "react"
import { useRoutes } from "react-router-dom"
import router from "./router"

function App() {
  return useRoutes(router)
}

// 相当于这样
const App = () => {
  // 使用Router组件包裹整个应用
  <Router>
  	<Routes>
    	<Route path="/" element={<LayoutRoot />}>
        <Route index element={<Home />}</Route>
         {/* 会默认继承父级的path '/' */}
         <Route path="bar" element={<Bar />}</Route> 
      </Route>
    </Routes>
  </Router>
}