最近接手了一个简单的项目,需要修改一些逻辑,时间也比较充裕,正好适合我这个小白边学边做。其中涉及了一些知识点,包括redux和router。所以今天先开始学习阮一峰大神的react router教程
看完这篇文章之后才知道react-router v4和v3有很大区别。在v4里面主要引用react-router-dom获得组件。
import { Router, Route, hashHistory } from 'react-router';
render((
<Router history={hashHistory}>
<Route path="/" component={App}/>
<Route path="/repos" component={Repos}/>
<Route path="/about" component={About}/>
</Router>
), document.getElementById('app'));
以上代码用户访问http://www.example.com/,实际会看到的是http://www.example.com/#/,访问的是App组件;用户访问/repos(比如http://localhost:8080/#/repos)时,加载Repos组件;访问/about(http://localhost:8080/#/about)时,加载About组件。
hashHistory 是一种路由的类型,但是有#,一般大家都不倾向于用这个。
二、嵌套路由
<Router history={hashHistory}>
<Route path="/" component={App}>
<Route path="/repos" component={Repos}/>
<Route path="/about" component={About}/>
</Route>
</Router>
上面代码中,用户访问/repos时,会先加载App组件,然后在它的内部再加载Repos组件。
一般用在通过左侧的菜单切换视图的情况里吧。App组件需要用this.props.children 把子路由传进去。
let routes = <Route path="/" component={App}>
<Route path="/repos" component={Repos}/>
<Route path="/about" component={About}/>
</Route>;
<Router routes={routes} history={browserHistory}/>
还可以将路由通过属性方式传给Router组件。
(暂时用不上,先不看了)
不以 / 开头的表示相对路径,匹配时会相对于父组件的路径。
需要注意的是,路由的匹配规则是从上到下,如果上一条匹配上了,下一条就不会匹配。
<Route path="/comments" ... />
<Route path="/comments" ... />
这个只会匹配第一个组件
<Router>
<Route path="/:userName/:id" component={UserPage}/>
<Route path="/about/me" component={About}/>
</Router>
这个只会匹配第一个,所以一般带参数的应该放在最后,可以当作默认组件来理解,一般默认的就是放在最后的。
<Router>
<Route path="/" component={App}>
<Route path="accounts" component={Accounts}/>
<Route path="statements" component={Statements}/>
</Route>
</Router>
以上代码当访问根路径/ 时,不会加载任何子组件,相当于只加载了一个空壳子。
<Router>
<Route path="/" component={App}>
<IndexRoute component={Home}/>
<Route path="accounts" component={Accounts}/>
<Route path="statements" component={Statements}/>
</Route>
</Router>
所以使用IndexRoute指定 ,访问根目录/时的的默认子组件为Home。
注意:IndexRoute组件没有路径参数path.
<Route path="inbox" component={Inbox}>
{/* 从 /inbox/messages/:id 跳转到 /messages/:id */}
<Redirect from="messages/:id" to="/messages/:id" />
</Route>
messages/:id 是相对路径,/messages/:id 是绝对路径。
现在访问/inbox/messages/5,会自动跳转到/messages/5。
<Route path="/" component={App}>
<IndexRedirect to="/welcome" />
<Route path="welcome" component={Welcome} />
<Route path="about" component={About} />
</Route>
render() {
return <div>
<ul role="nav">
<li><Link to="/about">About</Link></li>
<li><Link to="/repos">Repos</Link></li>
</ul>
</div>
}
Link 就是 <a>
元素的React版本。
如果链接到根路由用 IndexLink。因为用Link的时候使用 / 会匹配到任何子路由,IndexLink会精确匹配 /。
使用activeStyle ,activeClassName 可以修改当前路由的样式。(还没试过不知道好不好用)
使用Link组件的时候踩过一个坑,就是当Router和Route组件之间有自定义的组件时,使用Link会只更新url, 不更新组件。解决办法是用withRouter包裹该自定义组件。
类似于这样:
var Home = withRouter (connect()(() => <Link to={"Cal"}>Home 点击到子页面
</Link>))
具体参考链接https://blog.csdn.net/isaisai/article/details/78088823
2. History API
import { browserHistory } from 'react-router';
browserHistory.push('/some/path');
这个有坑,直接用的时候 url 变化了,组件没有刷新不知道为啥。
应该还记得最开始给Router传的那个history属性吧,当时传了一个hashHistory 属性给它。除了这个属性,还有别的属性:
browserHistory和createMemoryhistory。
hashHistory 的表现形式很明显,就是有一个# ,看上去很不美观。所以倾向于使用browserHistory, 这个就是背后调用了浏览器的History API。但是这个情况需要对服务器改造,否则用户直接向服务器请求子路由会显示网页找不到的404错误???这个怎么办我也不知道。createMemoryHistory是个啥,我也不知道!!!
每个路由都有钩子,用户进入或离开的时候触发。
<Route path="about" component={About} />
<Route path="inbox" component={Inbox}>
<Redirect from="messages/:id" to="/messages/:id" />
</Route>
上面的代码中,如果用户离开/messages/:id,进入/about时,会依次触发以下的钩子。
使用场景:
十、和Redux
v4: 以前react-router-redux里创建浏览器历史对象的方法也没有了,需要直接导入history这个npm。