react-router-dom
react-router与react-router-dom的区别
- react-router: 实现了路由的核心功能
- react-router-dom: 基于react-router,加入了在浏览器运行环境下的一些功能,例如: Link组件,会渲染一个a标签,Link组件源码a标签行; BrowserRouter和HashRouter组件,前者使用pushState和popState事件构建路由,后者使用window.location.hash和hashchange事件构建路由
- react-router-dom依赖react-router,所以我们使用npm安装依赖的时候,只需要安装相应环境下的库即可,不用再显式安装react-router。基于浏览器环境的开发,只需要安装react-router-dom
安装:npm i -S react-router-dom
引用及配置
在index.js中,包裹根组件,不在这包裹在app.js中也是一样的,只要最后包裹的是渲染的根路径,就表示开启了路由功能
路由两种模式:HashRouter, BrowserRouter
1 import { HashRouter, BrowserRouter } from "react-router-dom";
2 ReactDOM.render( 3 <BrowserRouter> 4 <App></App> 5 </BrowserRouter>, 6 document.getElementById("app") 7 );
静态路由跳转
1. 根组件app.js里
import { Switch, Route, Link, Redirect } from "react-router-dom";
Link 页面跳转 属性 to,还有 NavLink
![](https://img2020.cnblogs.com/blog/1778086/202104/1778086-20210412135810651-427002838.png)
Route 相当于路由占位符 path属性:路由匹配的路径 component属性:路由对应的组件
Switch 阻止路由重复渲染
Redirect 重定向路由,from=会进行正则匹配。只能用在<Switch>中
exact 启用精准匹配,否则模糊匹配,最好不要用
1 import React from "react"; 2 import { Switch, Route, Link, Redirect } from "react-router-dom"; 3 import Home from "./components/Home.jsx"; 4 import User from "./components/User.jsx"; 5 6 export default function App() { 7 return ( 8 <div> 9 <div> 10 <Link to="/home">首页</Link> // 这两个link标签,就是根组件渲染的dom,一般PC端点击侧边栏切换路由,而移动端在则不需要这一块,除非是下面的tabbar 11 <Link to="/user">个人中心</Link> 12 </div> 13 <Switch> 14 <Redirect from="/" to="/home" exact/> 15 <Route exact path="/home" component={Home}></Route> 16 <Route exact path="/user" component={User}></Route> 17 </Switch> 18 </div> 19 ); 20 }
2. home.jsx组件里
第一种:声明式 通过link 的 to 属性
第二种:编程式(利用js函数)this.props.hestory.push()
import React from "react"; import { Link } from "react-router-dom"; export default class Home extends React.Component { render() { return ( <div> <Link to="/user">声明式跳转</Link> <div onClick={() => {this.tousertem()}}>编程式跳转/形式 </div> </div> ); } tousertem = () => { this.props.history.push('/user'); } }
路由传参
第一种:通过动态路由(声明式和编程式)参数会以 /5 的形式跟在url后面 (params)
优点:刷新页面参数还在,缺点:只能传递字符串,参数过多url丑
获取路由参数的方式:console.log(this.props.match.params)
1 // 首先 path路径 2 <Switch> 3 <Route exact path="/user/:id" component={User}></Route> 4 </Switch> 5 6 //然后 home页跳转 7 <Link to="/user/5">声明式跳转</Link> 8 9 <div onClick={() => {this.tousertem()}}>编程式跳转/形式</div> 10 11 tousertem = () => { 12 this.props.history.push('/user/'+'2'); 13 } 14 15 //最后 user组件没获取路由参数 16 export default class User extends React.Component { 17 componentDidMount() { 18 console.log(this.props.match.params, '动态路由获取参数') 19 } 20 }
第二种方式:通过query/state (声明式和编程式(js)) 参数以对象的形式,不会拼在url后面
一定要指定pathname,不能写path,否则报错
获取路由参数的方式:console.log(this.props.location.query, "路由参数");
1 // 首先path 路径 2 <Switch> 3 <Route exact path="/user" component={User}></Route> 4 </Switch>; 5 //然后home页面跳转 6 <Link to={{ pathname: "/user", query: { id: 1 } }}>声明式跳转</Link> 7 <div onClick={() => { this.touser() }}> 编程式跳转携带参数</div> 8 touser = () => { 9 this.props.history.push({ 10 pathname: "/user", 11 query: { 12 id: 100, 13 origanid: 10010, 14 }, 15 }); 16 }; 17 // 最后 user页面获取参数 18 export default class User extends React.Component { 19 componentDidMount() { 20 console.log(this.props); 21 console.log(this.props.location.query, "路由参数"); 22 } 23 }
props.history.listen()
只要是具备路由功能的组件都可以使用这个方法,参数接收一个回调函数,但是是有切换页面时才会触发这个方法,很像vue中的组件内的钩子,当路由变化的时候做一些事情
props.history.listen((e) => { console.log(e, '开启了withRouter') })