React Router DOM

官网地址

https://reactrouter.com/web/guides/quick-start

React Router 的组成部分

  1. react-router : 是浏览器与原生应用的公共部分。

  2. react-router-dom:是用于浏览器的。

  3. react-router-native: 是用于原生应用的。

react-router是核心部分。react-router-dom提供了浏览器使用需要的定制组件。react-router-native则专门提供了在原生移动应用中需要用到的部分。所以,如果在本例中实现浏览器开发就只需要安装react-router-dom

安装react-router-dom

执行以下命令

npm install react-router-dom --save

react-router

  1. Browser Router : 这是对Router接口的实现。使得页面和浏览器的history保持一致。如:window.location

  2. Hash Router : 和上面的一样,只是使用的是 URL 的hash部分,比如:window.location.hash

  3. Native Router: 处理react native内的路由。

  4. Static Router: 处理静态路由。

<BrowserRouter><HashRouter>是可以在浏览器中使用的。如果你使用的是一个非静态的站点、要处理各种不同的URL那么你就需要使用BrowserRouter。相反的如果你的server只处理静态的URL,那么就使用HashRouter。**

route

Route组件可以使用如下的属性:

  • path属性,字符串类型,它的值就是用来匹配url的。

  • component属性,它的值是一个组件。在path匹配成功之后会绘制这个组件。

  • exact属性,这个属性用来指明这个路由是不是排他的匹配。

  • strict属性, 这个属性指明路径只匹配以斜线结尾的路径。

还有其他的一些属性,可以用来代替component属性。

  • render属性,一个返回React组件的方法。传说中的rencer-prop就是从这里来的。

  • children属性,返回一个React组件的方法。只不过这个总是会绘制,即使没有匹配的路径的时候。

多数的时候是用component属性就可以满足。但是,某些情况下你不得不使用renderchildren属性。

  • match
  • location
  • history

如:

使用组件:   
<Route exact path="/" component={HomePage} />
使用`render`属性实现内联绘制:
<Route path="/" render={()=><div>HomePage</div>} />
const FadingRoute = ({ component, ...rest }) => (
  <Route {...rest} render={(props) => (
    <FadeIn>
      <componnet {...props} />
    </FadeIn>
  )} />
)

<FadingRoute path="/cool" component={Something} />
使用`children`:
<ul>
  <ListItemLink to="/somewhere" />
  <LinkItemLink to="/somewhere-else" />
</ul>

const ListItemLink = ({to, ...rest}) => (
  <Route path={to} children={({math}) => (
    <li className={match ? 'active' : ''}>
      <Link to={to} {...rest} />
    </li>
  )} />
)

URL / Path / Route 的参数

通常情况下,我们都会在路径里添加参数。这样方便在不同的组件之间传递一些必要的数据。那么我们如何才能获取到这些传递的参数,并传递给组件中呢?我们只需要在路径的最后加上/:param。如:

<Route path="/:param1" component={HomePage} />

const HomePage = ({match}) => (
  <div>
    <h1> parameter => {match.params.param1} </h1>
  </div>
);

一旦有路径可以匹配成功,那么就会穿件一个拥有如下属性的对象,并传入绘制的组件里:

  • url: 匹配的url。
  • path:就是path。
  • isExact:如果path和当前的widnow.location的path部分完全相同的话。
  • params:在URL里包含的参数。

Link

Link是react router v4特有的一个组件。是用来代替上一版的anchor link。使用Link可以在React应用的不同页面之间跳转。与unclor会重新加载整个页面不同,Link只会重新加载页面里和当前URL可以匹配的部分

Link组件需要用到to属性,这个属性的值就是react router要跳转到的地址。如:

import { Link } from 'react-router-dom';

const Nav = () => (
  <Link to '/'>Home</Link>
);

to属性的值可以是一个字符串,也可以是一个location(pathname, hash, state和search)对象。比如:

<Link to{{
  pathname: '/me',
  search: '?sort=asc',
  hash: '#hash',
  state: { fromHome: true }
}} />

< Link > 和< NavLink >

NavLinkLink的一个子类,在Link组件的基础上增加了绘制组件的样式,比如:

<NavLink to="/me" activeStyle={{SomeStyle}} activeClassName="selected">
  My Profile
</NavLink>

使用react-router-dom实现第一个demo

首先,引入必要的组件。比如:RouteBrowserRouter

import { BrowserRouter, Route } from 'react-router-dom';

创建一些组件和一些Html标签。同时我们用react router v4里的LinkNavLink组件。

const BaseLayout = () => (
  <div className="base">
    <header>
      <p>React Router v4 Browser Example</p>
      <nav>
        <ul>
          <li><Link ="/">Home</Link></li>
          <li><Link ="/about">About</Link></li>
          <li><Link ="/me">Profile</Link></li>
          <li><Link ="/login">Login</Link></li>
          <li><Link ="/register">Register</Link></li>
          <li><Link ="/contact">Contact</Link></li>
        </ul>
      </nav>
    </header>
    <div className="container">
      <Route path="/" exact component={HomePage} />
      <Route path="/about" component={AboutPage} />
      <Route path="/contact" component={ContactPage} />
      <Route path="/login" component={LoginPage} />
      <Route path="/register" component={RegisterPage} />
      <Route path="/me" component={ProfilePage} />
    </div>
    <footer>
      React Router v4 Browser Example (c) 2017
    </footer>
  </div>
);

const HomePage = () => <div>This is a Home Page</div>
const LoginPage = () => <div>This is a Login Page</div>
const RegisterPage = () => <div>This is a Register Page</div>
const ProfilePage = () => <div>This is a Profile Page</div>
const AboutPage = () => <div>This is a About Page</div>
const ContactPage = () => <div>This is a Contact Page</div>

App组件

const App = () => (
  <BrowserRouter>
    <BaseLayout />
  </BrowserRouter>
)

render(<App />, document.getElementById('root'));

非排他的路由

在上例中,我们在HomePage组件的路由里使用了属性exact

<Route path="/" exact component={HomePage} />

这是因为v4中的路由默认都是非排他的,这一点和v3的实现思路截然不同。如果没有exact属性,HomePage组件和其他的组件就会同事绘制在页面上。

如,当用户点了登录连接以后,"/""/login"都满足匹配条件,对应的登录组件和Home组件就会同时出现在界面上。但是,这不是我们期待的结果,所以我们要给"/"path加上exact属性。

现在我们来看看非排他的路由有什么优点。假如我们有一个子菜单组件需要显示在profile页面出现的时候也出现。我们可以简单的修改BasicLayout来实现。

const BaseLayout = () =>  (
  <div className="base">
    <header>
      <p>React Router v4 Browser Example</p>
      <nav>
        <ul>
          <li><Link to="/">Home</Link></li>
          <li><Link to="/about">About</Link></li>
          <li>
            <Link to="/me">Profile</Link>
            <Route path="/me" component={ProfileMenu} />
          </li>
          {/*略*/}
        </ul>
      </nav>
    </header>
  </div>
);

这样我们就会看到对应于"/me"路径的组件都绘制出来了。这就是非排他路由的好处。

排他路由

排他路由是react router v3的默认实现。只有第一个匹配的路由对应的组件会被绘制。这一点也可以用react router v4的Switch组件来实现。在Switch组件中,只有第一个匹配的路由<Route>或者<Redirect>会被绘制:

import { Switch, Route } from 'react-router';

<Switch>
  <Route exact path="/" component={HomePage} />
  <Route path="/about" component={AboutPage} />
  <Route path="me" component={ProfilePage} />
  <Route component={NotFound} />
</Switch>

浏览器历史

react router v4中,提供了一个history对象。这个对象包含了多个api,可以用来操作浏览器历史等。

你也可以在React应用里使用history对象的方法:

history.push("/my-path")
history.replace("/my-path")

用另外的方法可以写成:

<Link to="/my-path" />
<Redirect to="my-path" />

使用< Redirect >组件实现重定向

无论何时你要重定向到另外一个地址的时候,都可以使用Redirect组件:

<Redirect to {{
  pathname: '/register',
  search: '?utm=something',
  state: { referrer: someplage.com }
}}>

或者,更为简单的:

<Redirect to="register" />
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,456评论 5 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,370评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,337评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,583评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,596评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,572评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,936评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,595评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,850评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,601评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,685评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,371评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,951评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,934评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,167评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,636评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,411评论 2 342

推荐阅读更多精彩内容