本文共--字 阅读约--分钟 | 浏览: -- Last Updated: 2021-05-26
// 安装4.x版本的 react-route-dom 是包含了核心库 react-route的
// npm i react-route-dom -S
// import { Router } from 'react-route-dom'
// 这个Router是相当于是VueRouter的,负责包括所有的路由记录
// 但是本身是抽象的 不能直接使用 因为它不知道该使用哪种模式
// 它拥有四个子类:{BroswerRouter} {HashRouter} {StaticRouter} {MemoryRouter}
// BroswerRouter 对应 history模式
// HashRouter 对应 hash 模式
import { BrowserRouter as Router, Route } from 'react-router-dom'
class App extends React.Component {
render() {
return (
<Router>
<div>
{ /* exact 精准拼配 Router必须有一个根元素 */ }
<Route exact path="/" component={ Home } />
<Route path="/news" render={()=>(<h1>我是一个news组件</h1>)} />
</div>
</Router>
)
}
}
ReactDOM.render(<App/>, document.getElementById('app'))
import { HashRouter as Router,Route,Redirect } from 'react-router-dom'
<Router>
<div>
<Route path="/goods" component={Goods}/>
<Redirect to="/home" from="/" /> {/* /重定向到首页 */}
</div>
</Router>
<Route exact path="/" render={() => (
loggedIn ? (<Redirect to="/dashboard"/>) : (<PublicHomePage/>)
)}/>
<Redirect
to={{
pathname: "/login",
search: "?utm=your+face",
state: { referrer: currentLocation }
}}
/>
<Redirect push to="/somewhere/else" />
// push 是一个bool值,使用push而不是replace
import { HashRouter as Router,Route,Link, NavLink} from 'react-router-dom'
<Router>
<div>
{/* Link标签本质还是a便签 */}
<Link to="/home">首页</Link>
<Link to="/goods">商品</Link>
<hr/>
{/* 与route-link 差不多 会给激活的NavLink 添加一个active类 */}
<NavLink to="/home">首页</NavLink>
<hr/>
{/* 可以使用activeClassName自定义这个类名 一般使用第三方样式的时候使用 */}
<NavLink to="/home" activeClassName='myActive'>首页</NavLink>
<hr/>
{/* 也要加exact精准匹配 不然active类会在跳转到/home的时候 在两个NavLink标签上都加上 */}
<NavLink to="/" exact >Index</NavLink>
<NavLink to="/home">首页</NavLink>
<hr/>
<Route path="/goods" component={Goods}/>
{/* /重定向到首页 */}
<Redirect to="/home" from="/" />
</div>
</Router>
Switch
组件让路由在匹配到第一个组件时就结束匹配
import { HashRouter as Router,Route,Switch} from 'react-router-dom'
<Router>
<div>
{/*Switch一定要加 不然有多少个路由 每次跳转的时候就会匹配多少次 影响性能*/}
<Switch>
{/*在Switch中 如果默认路径不加 exact 不管跳转哪里都会跳转到Index 因为'/xxx'都会匹配到'/' */}
{/* exact是bool值 可以设置为false。exact={false} 实现的是 url.pathname === Route的path属性 */}
<Route exact path="/" component={Index}/>
<Route path="/home" component={Home}/>
<Route path="/goods" component={Goods}/>
</Switch>
</div>
</Router>
class App extends React.Component {
render (){
return (
<Router>
<Route path="/home" component={Home}/>
<Route path="/goods" component={Goods}/>
</Router>
)
}
}
class Goods extends React.Component {
render(){
return (
<Router>
{/* 必须要连接/goods 不然无法匹配 因为每次匹配都是从最外层开始 */}
{/* /goods 一定不能设置 exact 不然/goods/phone根本就匹配不到路由/goods */}
{/* 那Goods组件都不会渲染 更不会有子路由组件渲染的机会 */}
<Route path="/goods/phone" component={Phone}/>
<Route path="/goods/food" component={Food}/>
</Router>
)
}
}
class App extends React.Component {
render(){
return (
<Router>
<Route path="/home" component={Home}/>
<Route path="/goods/:myPath" component={Product}/>
</Router>
)
}
}
class Product extends React.Component {
render(){
return (
<Router>
<Route path="/goods/phone" component={Phone}/>
<Route path="/goods/food" component={Food}/>
</Router>
)
}
componentDidMount(){ // 一般在这个钩子中请求数据 渲染视图
console.log(this.props)
// 动态路由的props上有三个属性 history location match
// history 历史对象 == this.props.history.push() / this.props.history.replace() / goBack / go
// 编程式跳转
// location 当前地址信息对象 = 当前路由的 hash pathname search(?a=1&b=2) state
// match 匹配对象 拥有isExact params:{myPath:phone} path: '/:myPath' url: '/phone'
}
}
为什么要在componentDidMount
中获取数据:更新期4个钩子不能调用setState
所有创建周期的render
不行,然后componentWillMount
会被执行两次
动态路由需要在componentWillReceiveProps
获取数据,因为动态路由使用同一个组件,组件的componentDidMount
只会执行一次。