一、路由的基本使用
- 明确好界面中的导航区、展示区
- 导航区的a标签改为Link标签
<Link to="/xxxxx">Demo</Link>
- 展示区写Route标签进行路径的匹配
{}
<Route path='/xxxx' component={Demo}/>
{}
<Route path='/xxxx' element={<Demo/>}/>
- 的最外侧包裹了一个或,用来管理路由
ReactDOM.render(
<BrowserRouter>
<App />
</BrowserRouter>,
document.getElementById('root')
)
二、NavLink与封装NavLink
- NavLink可以实现路由链接的高亮,通过activeClassName指定样式名
- 标签体内容是一个特殊的标签属性
- 通过this.props.children可以获取标签体内容
三、路由传参
1. params传参
v5:
路由链接(携带参数):
<Link to={`/home/message/detail/${msg.id}/${msg.title}`}>{msgObj.title}</Link>
注册路由(声明接收) :
<Route path='/home/message/detail/:id/:title' component={Detail} />
接收参数 :
const { id,title } = this.props.match.params
v6:(使用函数组件,并且通过引入 useParams 来实现参数的接收)
路由链接(携带参数):
<Link to={`detail/${msg.id}/${msg.title}`}>{msg.title}</Link>
注册路由(声明接收):
<Routes>
<Route path='detail/:id/:title' element={<Detail/>} />
</Routes>
接收参数 :
import { useParams } from 'react-router-dom';
const params = useParams();
const {id,title} = params;
2. search传参
v5:
路由链接(携带参数):
<Link to={`/home/message/detail?id=${msg.id}&title=${msg.title}`}>{msgObj.title}</Link>
无需注册路由(正常注册) :
<Route path='/home/message/detail' component={Detail} />
接收参数 :
import {qs} from 'querystring'
const {search} = this.props.location;
const {id,title} = qs.parse(search.slice(1)); //截取
v6:(使用函数组件,并且通过引入 useSearchParams 来实现参数的接收)
路由链接(携带参数):
<Link to={`detail?id=${msg.id}&title=${msg.title}`}>{msg.title}</Link>
无需注册路由(正常注册):
<Routes>
<Route path='detail' element={<Detail/>} />
</Routes>
接收参数 :
import { useSearchParams } from 'react-router-dom';
const [params] = useSearchParams();
const id = params.get('id');
const title = params.get('title');
3. state参数(刷新界面也可以保留参数)
v5:
路由链接(携带参数):
<Link to={{pathname:'home/message/detail',state:{id:msg.id,title:msg.title}}}>{msg.title}<Link/>
无需注册路由(正常注册) :
<Route path='/home/message/detail' component={Detail} />
接收参数 :
const {id,title} = this.props.location.state
v6:(使用函数组件,并且通过引入 useLocation 来实现参数的接收)
路由链接(携带参数):
<Link to='detail' state={{id: msg.id, title: msg.title}}>{msg.title}</Link>
无需注册路由(正常注册):
<Routes>
<Route path='detail' element={<Detail/>} />
</Routes>
接收参数 :
import { useLocation } from 'react-router-dom';
const location = useLocation();
const {id,title} = location.state;
四、编程式路由导航
1. v5
// push跳转+携带params参数
this.props.history.push(`/home/message/detail/${id}/${title}`);
// push跳转+携带search参数
this.props.history.push(`/home/message/detail?id=${id}&title=${title}`);
// push跳转+携带state参数
this.props.history.push(`/home/message/detail`, { id, title });
// replace跳转+携带params参数
this.props.history.replace(`/home/message/detail/${id}/${title}`)
// replace跳转+携带search参数
this.props.history.replace(`/home/message/detail?id=${id}&title=${title}`)
// replace跳转+携带state参数
this.props.history.replace(`/home/message/detail`, { id, title });
// 前进
this.props.history.goForward();
// 回退
this.props.history.back();
// 前进或回退 ( go )
this.props.history.go(-2); //回退到前2条的路由
// 在一般组件中使用编程式路由导航 (非路由组件)
import {withRouter} from 'react-router-dom'
class Header extends Component {
// withRouter(Header)后,就可以在一般组件内部使用 this.props.history
//...
}
export default withRouter(Header) // 将一般组件包裹后返回,使一般组件的props中也携带路由相关的三个参数
2. v6
// v6版本编程导航使用 useNavigate (以下为引入代码)
import { useNavigate } from "react-router-dom";
export default function A() {
const navigate = useNavigate();
//...
}
// push跳转+携带params参数
navigate(`detail/${id}/${title}`);
// push跳转+携带search参数
navigate(`detail?id=${id}&title=${title}`);
// push跳转+携带state参数
navigate(`detail`, {state: { id, title }});
// replace跳转+携带params参数
navigate(`detail/${id}/${title}`, {replace: true})
// replace跳转+携带search参数
navigate(`detail?id=${id}&title=${title}`, {replace: true})
// replace跳转+携带state参数
navigate(`detail`, {state: { id, title }, replace: true});
// 前进
navigate(1);
// 回退
navigate(-1);
// 前进或回退 ( go )
navigate.go(-2); //回退到前2条的路由
withRouter v6已被移除,v6中一般组件也可以使用useNavigate跳转,不需要withRouter
五、BrowserRouter与HashRouter的区别
1. 底层原理不一样:
BrowserRouter使用的是H5的history API,不兼容IE9及以下版本。
HashRouter使用的是URL的哈希值。
2. path表现形式不一样
BrowserRouter的路径中没有#,例如: localhost:3000/demo/test
HashRouter的路径包含#,例如: localhost:3000/#/demo/test
3. 刷新后对路由state参数的影响
(1) BrowserRouter没有任何影响,因为state保存在history对象中
(2) HashRouter刷新后会导致路由state参数的丢失!!!
4. 备注: HashRouter可以用于解决一些路径错误相关的问题。
附:解决多级路径刷新页面样式丢失的问题
- public/index.html 中 引入样式时不写./ 写 /(常用)
- public/index.html 中 引入样式时不写 ./ 写 %PUBLIC_URL% (常用)
- 使用HashRouter包裹 App组件