7.Switch与404
目标
掌握Switch的用法
问题
Route组件的匹配成功之后并不会停止,它可能会匹配多个组件。
Switch
用Switch组件包裹多个Route
组件。
在Switch
组件下,不管有多少个Route的路由规则匹配成功,都只会渲染第一个匹配的组件
示例
import React from 'react' import ReactDom from 'react-dom' import { BrowserRouter as Router, Route, NavLink, Switch } from 'react-router-dom' const Home = () => <div>主页</div> const Article = () => <div>文章列表页</div> const ArticleDetail = () => <div>文章详情页</div> export default function App () { return ( <div> <h1>react路由基本使用</h1> <Router> <NavLink to="/">主页</NavLink> <NavLink to="/article">文章列表页</NavLink> <NavLink to="/article/123">文章详情页-123</NavLink> <hr /> <Switch> <Route path="/" exact component={Home} /> <Route path="/article" component={Article} /> <Route path="/article/123" component={ArticleDetail} /> </Switch> </Router> </div> ) } ReactDom.render(<App />, document.getElementById('root'))
8.处理404页
思路: 不设置path属性,将404页对应的路由放在switch内部的最后位置
import React from 'react' import ReactDom from 'react-dom' import { BrowserRouter as Router, Route, NavLink, Switch } from 'react-router-dom' const Home = () => <div>主页</div> const Article = () => <div>文章列表页</div> const ArticleDetail = () => <div>文章详情页</div> const Page404 = () => <div>Page404</div> export default function App () { return ( <div> <h1>react路由基本使用</h1> <Router> <NavLink to="/">主页</NavLink> <NavLink to="/article">文章列表页</NavLink> <NavLink to="/article/123">文章详情页-123</NavLink> <hr /> <Switch> <Route path="/" exact component={Home} /> <Route path="/article" component={Article} /> <Route path="/article/123" component={ArticleDetail} /> <Route component={Page404} /> </Switch> </Router> </div> ) } ReactDom.render(<App />, document.getElementById('root'))
通过Switch
组件非常容易的就能实现404错误页面的提示
9.页面跳转 Redirect
页面跳转
格式
<Redirect from="/" exact to="/comment" />
示例代码
import React from 'react' import ReactDom from 'react-dom' import { HashRouter, Route, Link, Redirect } from 'react-router-dom' import Search from './pages/Search.jsx' import Comment from './pages/Comment.jsx' export default function App () { return ( <div> <h1>react路由基本使用</h1> <HashRouter> <Switch> <Link to="/comment">评论</Link> <Link to="/search">搜索</Link> <Route path="/comment" component={Comment} /> <Route path="/search" component={Search} /> {/* <Route path="/" component={Comment} /> */} <Redirect from="/" to="/comment" /> </Switch> </HashRouter> </div> ) } ReactDom.render(<App />, document.getElementById('root'))
10.编程式导航
场景:
点击登录按钮,登录成功后,通过代码跳转到后台首页,如何实现?
页面跳转有两类方式:
- 用户点击链接跳转
- 写代码跳转-编程式导航
目标
掌握history对象的使用,会用它来跳转页面。
素材
index.jsx
import React from 'react' import ReactDom from 'react-dom' import { useHistory } from 'react-router' import './04.css' import { BrowserRouter as Router, Route, NavLink, Switch } from 'react-router-dom' import Login from './pages/Login' import Comment from './pages/Comment' import Search from './pages/Search' export default function App () { const history = useHistory() console.log(history) return ( <div> <h1>react编程式导航</h1> <Router> <NavLink to="/login">登录</NavLink> <NavLink to="/comment">评论</NavLink> <NavLink to="/search">搜索</NavLink> <hr /> <Switch> <Route path="/login" component={Login} /> <Route path="/comment" component={Comment} /> <Route path="/search" component={Search} /> </Switch> </Router> </div> ) } ReactDom.render(<App />, document.getElementById('root'))
11.编程式导航的格式
import {useHistory} from 'react-router' export default function App() { const history = useHistory() history.push('/find') // 前进或后退到某个页面,参数 n 表示前进或后退页面数量(比如:-1 表示后退到上一页) history.go(-1) // 进入/frend,并替换记录 history.replace('/frend') }
12.history.replace和push的区别
push:向历史记录中添加一条
replace:在历史记录中用目标记录来替换当前记录
示例
push
详情页 --> login页(push) ----> 主页
此时,从主页后退,会回到login页。
replace
详情页 --> login页(replace) ----> 主页
此时,从主页后退,会回到详情页。
13.动态路由与路由参数获取
目标
掌握动态路由及参数获取的用法
问题
如何设置如下路由匹配规则,以显示文章详情
1. <NavLink to="/article/1">文章1</NavLink> 2. <NavLink to="/article/2">文章2</NavLink>
动态路由
1. // 可以匹配 /article/1 /article/2 /article/xxx 2. <Route path="/article/:id" component={Article} />
说明:
- 上面的/:id 称为占位符。id可以改成其他的变量名。
- 占位符可以有多个。例如:
/article/:形参1/:形参2
在组件中接收到路由的参数
有两个方式:
- 通过
props
可以
function Article(props){ console.log(props.match.params.id) }
14.嵌套路由的配置
业务举例:网易云嵌套路由
掌握嵌套路由的使用。
不需要学习任何新内容
示例
核心代码
App () { return <Router> <ul> <li><NavLink to="/find">发现</NavLink></li> <li><NavLink to="/my">我的音乐</NavLink></li> <li><NavLink to="/frend">朋友</NavLink></li> </ul> <Switch> <Route path="/find" component={Find}></Route> <Route path="/my" component={My}></Route> <Route path="/frend" component={Frend}></Route> </Switch> </Router> }
Find.js
Find(){ return <Router> <ul> <li><NavLink to="/find/recommand">推荐</NavLink></li> <li><NavLink to="/find/top">排行榜</NavLink></li> <li><NavLink to="/find/list">歌单</NavLink></li> </ul> <Switch> <Route path="/find/recommand" component={Com1}></Route> <Route path="/my/top" component={Com2}></Route> <Route path="/frend/list" component={Com3}></Route> </Switch> </Router> }
注意
配置嵌套路由的时候,需要对路径进行处理,必须要先匹配到父级路由,才能匹配到子路由
15.路由小结
用到的组件:
HashRouter, BrowserRouter, Link, NavLink, Route, Redirect, Switch
执行过程
- 点击 Link 组件(a标签),修改了浏览器地址栏中的 url
- React 路由监听到地址栏 url 的变化 hashChange popState
- React 路由内部遍历所有 Route 组件,使用路由规则(path)与 pathname(hash)进行匹配
- 当路由规则(path)能够匹配地址栏中的 pathname(hash) 时,就展示该 Route 组件的内容