React Router4.0

React Router v4是對React Router的一次徹底重構,採用動態路由,遵循React中一切皆組件的思想,每一個Route(路由)都是一個普通的React組件。

BrowserRouter創建的URL形式如下:
http://react.com/some/path
HashRouter創建的URL形式如下:
http://react.com/#/some/path

使用BrowserRouter時,一般還需要對服務器進行配置,讓服務器能正確處理所有可能的URL.例如,當瀏覽器發送 http://react.com/some/pathhttp://react.com/some/path2兩...,服務器能夠返回正確的HTML頁面(也就是單頁面應用中唯一的html頁面).使用HashRouter則不存在這個問題,因爲hash部分的內容會被服務器自動忽略,真正有效的是hash前面的部分,而對於單頁面應用來說,這部分內容是固定的。

路由的配置

1.path

(1)當使用BrowserRouter時,path用來描述這個Route匹配的URL的pathname
(2)當使用HashRouter時,path用來描述這個Route匹配的URL的hash.

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的匹配部分。

3.Route渲染組件的方式

(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)=>(

<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;

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章