react router 4.0 react-router-dom
React router的模式:
- HashRouter
- 老浏览器的history,通过hashchange事件来监听url的变化情况
- BrowserRouter
- 新浏览器的history,借助了H5提供的createBrowserRouter来实现,通过监听popstate事件来实现(可以去掉地址栏的 #符号)
React router四个核心包
包名 Description
react-router React Router核心api
react-router-dom React Router的DOM绑定,在浏览器中运行不需要额外安装react-router
react-router-native React Native 中使用,而实际的应用中,其实不会使用这个。
react-router-config 静态路由的配置
使用流程演示
-
安装两个依赖包
$ yarn add react-router react-router-dom
-
在入口文件index.js中使用router
import { BrowserRouter as Router} from 'react-router-dom' ReactDOM.render( <Router> <App /> </Router> , document.getElementById('root'));
-
Route上面的属性
<Route path = "/home_title" render = { () => { return <div>titile</div>}} />
<Route parh = "/home_children" children = {
() => {
return(
<Home></Home>
)
}
}></Route>
- NavLink 路由激活
<NavLink to = '/home' activeClassName = "active"> 首页 </NavLink>
- exact 路径完全匹配 必须是一直的 / /home
<Route path = "/home" component = { Home } exact ></Route>
- 重定向组件 Redirect
<Redirect from = '/' to = "/home" />
一般配合Switch使用
<Switch>
<Redirect from = '/' to = "/home" exact/>
<Route path = "/home" exact component = { Home } ></Route>
<Route path = "/home/good" render = {()=> <div> home_food </div> } ></Route>
<Route path = "/category" component = { Category}></Route>
<Route path = "/shopcar" component = { Shopcar}></Route>
<Route path = "/mine" component = { Mine } ></Route>
</Switch>
-
二级路由
哪里需要就在哪里引入
import { Route } from 'react-router-dom'
-
路由( 当我们是 /category , 跳转 /categor/1 ) 路由组件可以通过componentWillReceiveProps compoenntDidMount来监听路由变化
-
App组件不是路由组件,不能监听路由的变化,使用非常规手段将App组件变成路由组件
- 使用高阶组件 withRouter
class App extends React.Component { render(){ return ( <div className="App"> <Head></Head> {/* <Route path = "/" exact component = {Home}></Route> */} <Switch> <Redirect from = '/' to = "/home" exact/> <Route path = "/home" exact component = { Home } ></Route> <Route path = "/category" component = { Category}></Route> <Route path = "/shopcar" component = { Shopcar}></Route> <Route path = "/mine" component = { Mine } ></Route> </Switch> <Foot></Foot> </div> ) } } export default withRouter(App);
-
Switch一定要写,它一次只渲染一个组件,如果不写,路由组件全部都会渲染出来
-
动态路由
-
路由传参 Link/NavLink 组件身上的to属性来传递 to = {{pathname,search,hash,state}}
-
路由接参
- id: this.props.match.params.id
- search: 先用querystring将search转换成object
const qs = require('querystring') let { search } = this.props.location // '?a=1&b=2' const { a, b } = qs.parse( search.slice(1) )
-
-
去头去尾 分类页面定向第一层
class App extends React.Component {
constructor () { //
super()
this.state = { //设置头尾显示的控制开关
headFlag: true,
footFlag: true
}
}
componentDidMount(){ //初始化要运行一次 也就是第一次打开路由时
this.redirect()
this.head_foot_handler()
}
componentWillReceiveProps( nextProps ){
//要用nextProps 即路由变化后的属性
let { pathname } = nextProps.location
this.redirect( pathname )
this.head_foot_handler( pathname )
}
redirect = ( pathname ) => {
// 使分类页面第一次打开就要显示第一类
let { history } = this.props
let path = pathname || this.props.location.pathname //要使初始化时候也要有参数
if( path === '/category'){
// 编程式导航 push replace
history.push('/category/1')
}
}
head_foot_handler = ( pathname ) => { //去头去尾
let path = pathname || this.props.location.pathname //要使初始化时候也要有参数
let arr = [ '/shopcar','/mine' ] //要去头的页面
let flag = true
arr.forEach ( item => {
if( item === path ){
flag = false
return
}
})
if( flag ){
// 没有匹配
this.setState({
headFlag:true
})
}else{
// 匹配到
this.setState({
headFlag:false
})
}
}