安装react-router和eact-router-dom
npm i react-router -s
npm i react-router-dom -s
使用包裹路由组件,最好就是全包括,就是在根组件上包括
import './App.css';
import {Component} from 'react'
// 引入
import {Routes, Route} from "react-router";
import {BrowserRouter} from 'react-router-dom'
// 引入 Home、Play、SongList组件
import Home from './components/home'
import Play from './components/play'
import SongList from './components/songList'
import NotFound from './components/NotFound'
class App extends Component {
render() {
return (
<BrowserRouter> {/*包裹着根组件*/}
{/*这个在下面会解释*/}
<div className="App">
{/*Link 组件,用来跳转路由的组件,to用来配置路由地址,
最终会渲染成 a 标签,也可以封装一下这个组件*/}
<Link to="/home">首页</Link>
<Link to="/play">播放页</Link>
<Link to="/songList">歌单页</Link>
{/* 路由出口 路由对应的组件会在这里进行渲染*/}
<Routes>
{/*指定路径和组件的对应关系,path代表路径 element代表组件 成对出现
path -> element*/}
<Route path="/" element={<Home/>}/>
<Route path="/home" element={<Home/>}/>
<Route path="/play" element={<Play/>}/>
<Route path="/songList" element={<SongList/>}/>
{/*兜底,如果上面的都匹配不到,就会渲染NotFound组件*/}
<Route path="*" element={<NotFound/>}/>
</Routes>
</div>
</BrowserRouter>
)
}
}
export default App;
这样的话,就可以点击页面上的链接或在地址栏进行输入地址,可以切换不同组件
遇见的问题:
最好在index.js渲染App组件时,在那里包括比较不容易出错
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<React.StrictMode>
<BrowserRouter>
<App/>
</BrowserRouter>
</React.StrictMode>
);
一个react只用一次,包裹整个应用
使用h5的history.pushState API 实现 (http://localhost:8000/home)
一般使用这个
使用URL的哈希值实现(http://localhost:8000/#/home)
通过 js 编程的方式进行路由页面跳转
// 导入useNavigate
import {useNavigate} from "react-router";
function Login() {
// 执行useNavigate()的得到一个跳转函数
const Navigate = useNavigate()
function goTo() {
// 调用跳转函数传入目标路径
Navigate('/home')
// Navigate('/home',{replace:true}) 可以配置额外得参数replace为true,
//表示不想加历史记录
// Navigate('/home',{replace:true},state:{id:"001"}) 也可以传递state参数
}
return (
<div>
<h1>这是login</h1>
<button onClick={goTo}>跳转到home</button>
</div>
)
}
export default Login
/home?id=1001&name="tom"&gender="男"
传参
Navigate('/home?id=1001')
取参
import React from 'react';
import {useSearchParams} from "react-router-dom";
function Home() {
const [params] = useSearchParams()
// params 是一个对象 对象里有一个get的方法
// 用来获取对应的参数
// 把参数的名称作为get的实参传过来
let id = params.get('id')
return (
<div>
这是首页,得到的参数id为:{id}
</div>
)
}
使用
/home/id=1001
跳转路由
Navigate('/home/id=1001')
与之对应的路由配置
<Route path="/home/:id" element={<Home/>}/>
取参
import React from 'react';
import {useParams} from "react-router-dom";
function Home() {
const params = useParams()
let id = params.id
return (
<div>
这是首页,得到的参数id为:{id}
</div>
)
}
export default Home;
传参
<Link
to="/play"
state={{
id:"001",
title:"标题",
gen:"不错"
}}
>播放页</Link>
接收参数
import React from 'react';
import {useLocation} from "react-router";
function Play() {
const state = useLocation()
console.log(state)
return (
<div>
这是播放页
</div>
)
}
export default Play;
配置home的二级路由
<Routes>
{/*指定路径和组件的对应关系,path代表路径 element代表组件 成对出现
path -> element*/}
<Route path="/" element={<Play/>}></Route>
<Route path="/home" element={<Home/>}>
{/*Home的二级路由*/}
{/*默认渲染的二级路由,添加一个index属性,path去掉*/}
<Route index element={<HomeA/>}/>
<Route path="/home/a" element={<HomeA/>}/>
<Route path="/home/b" element={<HomeB/>}/>
</Route>
<Route path="/play" element={<Play/>}/>
<Route path="/songList" element={<SongList/>}/>
<Route path="/login" element={<Login/>}/>
</Routes>
在home.jsx中
import {Outlet} from "react-router";
function Home() {
return (
<div>
啦啦啦啦
{/*二级路由出口位置*/}
<Outlet></Outlet>
</div>
)
}
export default Home;
路由过多的时候我们可以拆分成一个个路由表
如上述
<Routes>
<Route path="/" element={<Play/>}></Route>
<Route path="/home" element={<Home/>}>
{/*Home的二级路由*/}
<Route index element={<HomeA/>}/>
<Route path="/home/a" element={<HomeA/>}/>
<Route path="/home/b" element={<HomeB/>}/>
</Route>
<Route path="/play" element={<Play/>}/>
<Route path="/songList" element={<SongList/>}/>
<Route path="/login" element={<Login/>}/>
{/*兜底,如果上面的都匹配不到,就会渲染NotFound组件*/}
<Route path="*" element={<Login/>}/>
</Routes>
可以把这部分抽离出来,新建一个路由js文件。类似于Vue的 router-view
import Play from '../components/play'
import Home from "../components/home";
import HomeA from "../components/home/HomeA";
import HomeB from "../components/home/HomeB";
import {Navigate} from "react-router";
import SongList from "../components/songList";
import Login from "../components/login";
const routes = [
{
path: '/',
element: <Play/>
},
{
path: '/home',
element: <Home/>,
children: [
{
path:'a',
element:<HomeA/>
},
{
path:'b',
element: <HomeB/>
},
{
path:'',
element: <Navigate to="/home/b"/>
}
]
},
{
path:'/play',
element: <Play/>
},
{
path:'/songList',
element: <SongList/>
},
{
path:'/login',
element: <Login/>
}
]
export default routes
使用路由表
import './App.css';
import { Link} from 'react-router-dom'
import {useRoutes} from "react-router";
import routes from './routes'
function App() {
const element = useRoutes(routes)
return (
<div className="App">
<Link to="/home">首页</Link>
<Link to="/play">播放页</Link>
<Link to="/songList">歌单页</Link>
{element}
</div>
)
}
export default App;