React学习:路由定义及传参、数据复用-学习笔记
在React中使用react-router-dom路由
使用React构建的单页面应用,要想实现页面间的跳转,首先想到的就是使用路由。在React中,常用的有两个包可以实现这个需求,react-router 和react-router-dom 。
安装 首先进入项目目录,使用npm安装react-router-dom:
cnpm install react-router-dom --save
涉及知识点: 一般一个路由的至少会有三大组件,分别是BrowserRouter 、Route 、Link ; BrowserRouter :可以将其理解为一个容器,用来放Route、Link。 Route :可以理解为当前要展示的视图,会根据路由中不同的路径呈现不同展示。Route会有三大props,分别是location、history、match ;其中match有包含params、isExact、path、url这些属性。 Link :申明了路由的路由,要跳转的地方,简单的可以理解为“要到哪去”。
常用API 路由容器组件 BrowserRouter : 浏览器自带的API,restful风格(需要后台做相应的调整); HashRouter : 使用hash方式进行路由; MemoryRouter : 在内存中管理history,地址栏不会变化。在reactNative中使用。
Route标签 该标签有三种渲染方式component 、render 、children (绝大多数情况使用component组件就好了); 三种渲染方式都会得到三个属性match、history、location ; 渲染组件时,route props 跟着一起渲染; children方式渲染会不管地址栏是否匹配都渲染一些内容,在这里加动画一时很常见的做法。
Link标签 to : 后面可以接字符串,也可以跟对象(对象可以是动态地添加搜索的信息); replace : 当设置为true时,点击链接后将使用新地址替换掉访问历史记录里面的原地址。
NavLink标签 <NavLink> 是<Link> 的一个特定版本, 会在匹配上当前URL的时候会给已经渲染的元素添加样式参数; activeClassName ,当地址匹配时添加相应class; activeStyle ,当地址匹配时添加相应style; exact ,当地址完全匹配时,才生效; isActive ,添加额外逻辑判断是否生效。
Prompt标签 when : when的属性值为true时启用防止转换; message : 后面可以跟简单的提示语,也可以跟函数,函数是有默认参数的。
Redirect标签 <Redirect/> 可以写在<Route/> 的render 属性里面,也可以跟<Route/> 平级; to : 依旧是可以跟字符串或对象; push : 添加该属性时,地址不会被覆盖,而是添加一条新纪录; from : 重定向,与<Route/> 平级时。
match params : 通过解析URL中动态的部分获得的键值对; isExact : 当为true时,整个URL都需要匹配; path : 在需要嵌套<Route/> 的时候用到; url : 在需要嵌套<Link/> 的时候会用到;
获取方式:
this.props.match
导入方式:
import {
BrowserRouter as Router,
Route,
Link,
Switch
Redirect
Prompt
} from 'react-router-dom'
react-router和react-router-dom的区别是什么呢? 为什么有时候我们看到如下的写法: 写法1:
import {Swtich, Route, Router, HashHistory, Link} from 'react-router-dom';
写法2:
import {Switch, Route, Router} from 'react-router';
import {HashHistory, Link} from 'react-router-dom';
react-router : 实现了路由的核心功能 react-router-dom : 基于react-router,加入了在浏览器运行环境下的一些功能,例如:Link组件,会渲染一个a标签,Link组件源码a标签行; BrowserRouter和HashRouter组件
其他函数 replace 有些场景下,重复使用push或a标签跳转会产生死循环,为了避免这种情况出现,react-router-dom提供了replace。在可能会出现死循环的地方使用replace来跳转:
this.props.history.replace('/detail');
goBack 场景中需要返回上级页面的时候使用:
this.props.history.goBack();
简单例子
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import Routes from './project/routes'
import * as serviceWorker from './serviceWorker';
ReactDOM.render(
<React.StrictMode>
<Routes />
</React.StrictMode>,
document.getElementById('root')
);
serviceWorker.unregister();
import React,{Component} from 'react';
import {BrowserRouter as Router, Route} from 'react-router-dom'
import Home from './home/index'
import Login from './login/index'
class Routes extends Component {
render(){
return (
<Router>
<div>
<Route path='/login' component={Login} ></Route>
<Route path='/index' component={Home} ></Route>
</div>
</Router>
)
}
}
export default Routes;
路由定义及传参
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import 'antd/dist/antd.css'
import Routes from './project/routes/routes'
import * as serviceWorker from './serviceWorker';
ReactDOM.render(
<React.StrictMode>
<Routes />
</React.StrictMode>,
document.getElementById('root')
);
serviceWorker.unregister();
路由传参:
import React,{Component} from 'react';
import {BrowserRouter as Router, Route, Link} from 'react-router-dom'
import Banner from '../other/banner'
class Music extends Component {
render(){
return <h1>Music {this.props.location.query}</h1>
}
}
class Category extends Component {
render(){
return <h1>Category {this.props.match.params.id}</h1>
}
}
class Routes extends Component {
constructor(){
super();
this.state = {
n:999
}
}
render(){
return (
<Router>
{}
<ul>
<li>
<Link to='/index/1/10'>首页</Link>
</li>
<li>
<Link to={'/tool/'+this.state.n}>工具模块</Link>
</li>
<li>
<Link to={{pathname:'/music',query:'123456'}}>音乐模块</Link>
</li>
</ul>
{}
<div>
<Route path='/tool/:id' component={Category} ></Route>
<Route path='/index/:id/:size' component={Banner} ></Route>
<Route path='/music' component={Music} ></Route>
</div>
</Router>
)
}
}
export default Routes;
若将routes写到另一个文件中,动态加载:
import React,{Component} from 'react';
import Banner from '../other/banner'
class Music extends Component {
render(){
return <h1>Music</h1>
}
}
class Category extends Component {
render(){
return <h1>Category </h1>
}
}
let routes = [
{
path:'/index',
component:Banner
},
{
path:'/tool',
component:Category
},
{
path:'/music',
component:Music
}
]
export default routes;
import React,{Component} from 'react';
import {BrowserRouter as Router, Route, Link} from 'react-router-dom'
import routes from './index'
class Routes extends Component {
constructor(){
super();
this.state = {
n:999
}
}
render(){
return (
<Router>
{}
<ul>
<li>
<Link to='/index'>首页</Link>
</li>
<li>
<Link to='/tool'>工具模块</Link>
</li>
<li>
<Link to='/music'>音乐模块</Link>
</li>
</ul>
{}
<div>
{
routes.map((item,i)=>{
return <Route key={i} path={item.path} component={item.component} ></Route>
})
}
</div>
</Router>
)
}
}
export default Routes;
|