React Router v4是對React Router的一次完全重構,採用動態路由,遵循React中一切皆組件的思想,每個Route(路由)都是一個普通的React組件。html
BrowserRouter建立的URL形式以下:
http://react.com/some/path
HashRouter建立的URL形式以下:
http://react.com/#/some/pathreact
使用BrowserRouter時,通常還須要對服務器進行配置,讓服務器能正確處理全部可能的URL.例如,當瀏覽器發送 http://react.com/some/path 和 http://react.com/some/path2兩...,服務器可以返回正確的HTML頁面(也就是單頁面應用中惟一的html頁面).使用HashRouter則不存在這個問題,由於hash部分的內容會被服務器自動忽略,真正有效的是hash前面的部分,而對於單頁面應用來講,這部份內容是固定的。瀏覽器
路由的配置服務器
1.pathreact-router
(1)當使用BrowserRouter時,path用來描述這個Route匹配的URL的pathname
(2)當使用HashRouter時,path用來描述這個Route匹配的URL的hash.dom
2.match函數
(1)params: Route的path能夠包含參數,例如:<Route path='/foo/:id'> 包含一個參數id。params就是用於從匹配的URL中解析出path中的參數,例如:當URL="http://react.com/foo/1時,params={id:1}。
(2)isExact: 是一個布爾值,當URL徹底匹配時,值爲true;當URL部分匹配時,值爲false.例如:當path="/foo",URL="http://react.com/foo"時,是徹底匹配;當URL="http://react.com/foo/1時,是部分匹配。
(3)path: Route的path屬性,構建嵌套路由時會使用到。
(4)url: URL的匹配部分。post
3.Route渲染組件的方式url
(1)component
component的值是一個組件,當URL和Route匹配時,component屬性定義的組件就會被渲染。
<Route path='/foo' component={FOO}>
當URL="http://react.com/foo"時,Foo組件會被渲染。
(2)render
render的值是一個函數,這個函數返回一個React元素,這個函數返回一個React元素。這種方式能夠很方便的爲待渲染的組件傳遞額外的屬性。
例如:
<Route path='/foo' render={(props)=>(code
<Foo {...props} data={extraProps} />
)}>
Foo組件接收了一個額外的data屬性。
(3)children children的值也是一個函數,函數返回要渲染的React元素。與以前兩種方式不一樣的是,不管是否匹配成功,children返回的組件都將會被渲染。可是當匹配不成功時,match屬性爲null。例如:
<Route path='/foo' children={(props)=>(
<div className={props.match?'active':''}> <Foo /> </div>
)} />
若是Route匹配當前URL,待渲染元素的根節點div的class將被設置成active。
4.Switch和exact
當URL和多個Route匹配時,這些Route都會執行渲染操做。若是隻想讓第一個匹配的Router渲染,那麼能夠把這些Route包到一個Switch組件中。
若是想讓URL和Route徹底匹配時,Route才渲染,那麼可使用Route的exact屬性。Switch和exact經常聯合使用,用於應用首頁的導航。
例如:
<Router>
<Switch> <Route exact path='/' component={Home} /> <Route path='/posts' component={Posts} /> <Route path='/:user' component={User} /> </Switch>
</Router>
若是不使用Switch,當URL的pathname爲"/posts"時,<Route path='/posts'/>和<Route path='/:user' />都會被匹配。
若是不使用exact,"/" "/posts" "/user1"等幾乎全部URL都會匹配第一個Route,又由於Switch的存在,後面的兩個Route永遠也不會被匹配。使用exact,保證只有當URL的pathname爲"/"時,第一個Route纔會被匹配。
5.嵌套路由
嵌套路由是指在Route渲染的組件內部定義新的Route.例如:
const Posts = ({match}) => {
return( <div> {/*這裏match.url等於/posts*/} <Route path={`${match.url}/:id`} component={PostDetail} /> <Route exact path={match.url} component={PostList} /> </div> )
}
當URL的pathname爲"/posts/react"時,PostDetail組件會被渲染;當URL的pathname爲"/posts"時,PostList組件會被渲染。Route的嵌套使用讓應用能夠更加靈活的使用路由。
6.連接
Link是React Router提供的連接組件,一個Link組件定義了當點擊該Link時,頁面應該如何路由:
例如:
const Navigation = () => (
<header> <nav> <ul> <li><Link to='/'>Home</Link></li> <li><Link to='/posts'>Posts</Link></li> </ul> </nav> </header>
)
Link使用to屬性聲明要導航到URL地址。to能夠是string或object類型,當to爲object類型時,能夠包含pathname、search、hash、state、四個屬性,例如:
<Link to={{
pathname:'/posts', search:'?sort=name', hash:'#the-hash", state:{formHome:true}
}}/>
除了使用Link外,咱們還可使用history對象手動實現導航,history中最經常使用的方法是push(path,[state])和replace(path,[state]),push會向瀏覽器歷史記錄中新增一條記錄,replace會用新紀錄替換當前紀錄,例如:
history.push('/posts')
history.replace('/posts')
import React from "react";
import { BrowserRouter as Router, Route, Link } from "react-router-dom";
function BasicExample() {
return (
<Router> <div> <ul> <li> <Link to="/">Home</Link> </li> <li> <Link to="/about">About</Link> </li> <li> <Link to="/topics">Topics</Link> </li> </ul> <hr /> <Route exact path="/" component={Home} /> <Route path="/about" component={About} /> <Route path="/topics" component={Topics} /> </div> </Router>
);
}
function Home() {
return (
<div> <h2>Home</h2> </div>
);
}
function About() {
return (
<div> <h2>About</h2> </div>
);
}
function Topics({ match }) {
return (
<div> <h2>Topics</h2> <ul> <li> <Link to={`${match.url}/rendering`}>Rendering with React</Link> </li> <li> <Link to={`${match.url}/components`}>Components</Link> </li> <li> <Link to={`${match.url}/props-v-state`}>Props v. State</Link> </li> </ul> <Route path={`${match.path}/:topicId`} component={Topic} /> <Route exact path={match.path} render={() => <h3>Please select a topic.</h3>} /> </div>
);
}
function Topic({ match }) {
return (
<div> <h3>{match.params.topicId}</h3> </div>
);
}
export default BasicExample;