官方英文文档 - https://reacttraining.com/rea...
版本 -v4.2.0
<BrowserRouter>
使用 HTML5 提供的 history API (pushState
, replaceState
和 popstate
事件) 来保持 UI 和 URL 的同步。html
import { BrowserRouter } from 'react-router-dom'; <BrowserRouter basename={string} forceRefresh={bool} getUserConfirmation={func} keyLength={number} > <App /> </BrowserRouter>
全部位置的基准 URL。若是你的应用程序部署在服务器的子目录,则须要将其设置为子目录。basename
的正确格式是前面有一个前导斜杠,但不能有尾部斜杠。node
<BrowserRouter basename="/calendar"> <Link to="/today" /> </BrowserRouter>
上例中的 <Link>
最终将被呈现为:react
<a href="/calendar/today" />
若是为 true
,在导航的过程当中整个页面将会刷新。通常状况下,只有在不支持 HTML5 history API 的浏览器中使用此功能。git
const supportsHistory = 'pushState' in window.history; <BrowserRouter forceRefresh={!supportsHistory} />
用于确认导航的函数,默认使用 window.confirm。例如,当从 /a
导航至 /b
时,会使用默认的 confirm
函数弹出一个提示,用户点击肯定后才进行导航,不然不作任何处理。译注:须要配合 <Prompt>
一块儿使用。github
// 这是默认的确认函数 const getConfirmation = (message, callback) => { const allowTransition = window.confirm(message); callback(allowTransition); } <BrowserRouter getUserConfirmation={getConfirmation} />
location.key
的长度,默认为 6
。web
<BrowserRouter keyLength={12} />
要呈现的单个子元素(组件)。ajax
<HashRouter>
使用 URL 的 hash
部分(即 window.location.hash
)来保持 UI 和 URL 的同步。npm
import { HashRouter } from 'react-router-dom'; <HashRouter> <App /> </HashRouter>
注意: 使用hash
记录导航历史不支持location.key
和location.state
。在之前的版本中,咱们视图 shim 这种行为,可是仍有一些问题咱们没法解决。任何依赖此行为的代码或插件都将没法正常使用。因为该技术仅用于支持旧式(低版本)浏览器,所以对于一些新式浏览器,咱们鼓励你使用<BrowserHistory>
代替。
全部位置的基准 URL。basename
的正确格式是前面有一个前导斜杠,但不能有尾部斜杠。react-native
<HashRouter basename="/calendar"> <Link to="/today" /> </HashRouter>
上例中的 <Link>
最终将被呈现为:api
<a href="#/calendar/today" />
用于确认导航的函数,默认使用 window.confirm。
// 这是默认的确认函数 const getConfirmation = (message, callback) => { const allowTransition = window.confirm(message); callback(allowTransition); } <HashRouter getUserConfirmation={getConfirmation} />
window.location.hash
使用的 hash
类型,有以下几种:
slash
- 后面跟一个斜杠,例如 #/ 和 #/sunshine/lollipopsnoslash
- 后面没有斜杠,例如 # 和 #sunshine/lollipopshashbang
- Google 风格的 ajax crawlable,例如 #!/ 和 #!/sunshine/lollipops默认为 slash
。
要呈现的单个子元素(组件)。
为你的应用提供声明式的、可访问的导航连接。
import { Link } from 'react-router-dom'; <Link to="/about">About</Link>
一个字符串形式的连接地址,经过 pathname
、search
和 hash
属性建立。
<Link to='/courses?sort=name' />
一个对象形式的连接地址,能够具备如下任何属性:
pathname
- 要连接到的路径search
- 查询参数hash
- URL 中的 hash,例如 #the-hashstate
- 存储到 location 中的额外状态数据<Link to={{ pathname: '/courses', search: '?sort=name', hash: '#the-hash', state: { fromDashboard: true } }} />
当设置为 true
时,点击连接后将替换历史堆栈中的当前条目,而不是添加新条目。默认为 false
。
<Link to="/courses" replace />
容许访问组件的底层引用。
const refCallback = node => { // node 指向最终挂载的 DOM 元素,在卸载时为 null } <Link to="/" innerRef={refCallback} />
你还能够传递一些其它属性,例如 title
、id
或 className
等。
<Link to="/" className="nav" title="a title">About</Link>
一个特殊版本的 <Link>
,它会在与当前 URL 匹配时为其呈现元素添加样式属性。
import { NavLink } from 'react-router-dom'; <NavLink to="/about">About</NavLink>
当元素处于激活状态时应用的类,默认为 active
。它将与 className
属性一块儿使用。
<NavLink to="/faq" activeClassName="selected">FAQs</NavLink>
当元素处于激活状态时应用的样式。
const activeStyle = { fontWeight: 'bold', color: 'red' }; <NavLink to="/faq" activeStyle={activeStyle}>FAQs</NavLink>
若是为 true
,则只有在位置彻底匹配时才应用激活类/样式。
<NavLink exact to="/profile">Profile</NavLink>
若是为 true
,则在肯定位置是否与当前 URL 匹配时,将考虑位置的路径名后面的斜杠。有关更多信息,请参阅 <Route strict> 文档。
<NavLink strict to="/events/">Events</NavLink>
添加额外逻辑以肯定连接是否处于激活状态的函数。若是你要作的不只仅是验证连接的路径名与当前 URL 的路径名相匹配,那么应该使用它。
// 只有当事件 id 为奇数时才考虑激活 const oddEvent = (match, location) => { if (!match) { return false; } const eventID = parseInt(match.params.eventID); return !isNaN(eventID) && eventID % 2 === 1; } <NavLink to="/events/123" isActive={oddEvent}>Event 123</NavLink>
isActive
默认比较当前历史位置(一般是当前的浏览器 URL)。你也能够传递一个不一样的位置进行比较。
用于在位置跳转以前给予用户一些确认信息。当你的应用程序进入一个应该阻止用户导航的状态时(好比表单只填写了一半),弹出一个提示。
import { Prompt } from 'react-router-dom'; <Prompt when={formIsHalfFilledOut} message="你肯定要离开当前页面吗?" />
当用户试图离开某个位置时弹出的提示信息。
<Prompt message="你肯定要离开当前页面吗?" />
将在用户试图导航到下一个位置时调用。须要返回一个字符串以向用户显示提示,或者返回 true
以容许直接跳转。
<Prompt message={location => { const isApp = location.pathname.startsWith('/app'); return isApp ? `你肯定要跳转到${location.pathname}吗?` : true; }} />
译注:上例中的
location
对象指的是下一个位置(即用户想要跳转到的位置)。你能够基于它包含的一些信息,判断是否阻止导航,或者容许直接跳转。
在应用程序中,你能够始终渲染 <Prompt>
组件,并经过设置 when={true}
或 when={false}
以阻止或容许相应的导航,而不是根据某些条件来决定是否渲染 <Prompt>
组件。
译注:when
只有两种状况,当它的值为true
时,会弹出提示信息。若是为false
则不会弹出。见 阻止导航示例。
<Prompt when={true} message="你肯定要离开当前页面吗?" />
将 URL 的历史记录保存在内存中的 <Router>
(不读取或写入地址栏)。在测试和非浏览器环境中颇有用,例如 React Native。
import { MemoryRouter } from 'react-router-dom'; <MemoryRouter> <App /> </MemoryRouter>
历史堆栈中的一系列位置信息。这些多是带有 {pathname, search, hash, state}
的完整位置对象或简单的字符串 URL。
<MemoryRouter initialEntries={[ '/one', '/two', { pathname: '/three' } ]} initialIndex={1} > <App/> </MemoryRouter>
initialEntries
数组中的初始位置索引。
用于确认导航的函数。当 <MemoryRouter>
直接与 <Prompt>
一块儿使用时,你必须使用此选项。
location.key
的长度,默认为 6
。
要呈现的单个子元素(组件)。
使用 <Redirect>
会导航到一个新的位置。新的位置将覆盖历史堆栈中的当前条目,例如服务器端重定向(HTTP 3xx)。
import { Route, Redirect } from 'react-router-dom'; <Route exact path="/" render={() => ( loggedIn ? ( <Redirect to="/dashboard" /> ) : ( <PublicHomePage /> ) )} />
要重定向到的 URL,能够是 path-to-regexp 可以理解的任何有效的 URL 路径。全部要使用的 URL 参数必须由 from
提供。
<Redirect to="/somewhere/else" />
要重定向到的位置,其中 pathname
能够是 path-to-regexp 可以理解的任何有效的 URL 路径。
<Redirect to={{ pathname: '/login', search: '?utm=your+face', state: { referrer: currentLocation } }} />
上例中的 state
对象能够在重定向到的组件中经过 this.props.location.state
进行访问。而 referrer
键(不是特殊名称)将经过路径名 /login
指向的登陆组件中的 this.props.location.state.referrer
进行访问。
若是为 true
,重定向会将新的位置推入历史记录,而不是替换当前条目。
<Redirect push to="/somewhere/else" />
要从中进行重定向的路径名,能够是 path-to-regexp 可以理解的任何有效的 URL 路径。全部匹配的 URL 参数都会提供给 to
,必须包含在 to
中用到的全部参数,to
未使用的其它参数将被忽略。
只能在 <Switch>
组件内使用 <Redirect from>
,以匹配一个位置。有关更多细节,请参阅 <Switch children>。
<Switch> <Redirect from='/old-path' to='/new-path' /> <Route path='/new-path' component={Place} /> </Switch>
// 根据匹配参数进行重定向 <Switch> <Redirect from='/users/:id' to='/users/profile/:id' /> <Route path='/users/profile/:id' component={Profile} /> </Switch>
译注:通过实践,发现以上“根据匹配参数进行重定向”的示例存在bug,没有效果。to
中的:id
并不会继承from
中的:id
匹配的值,而是直接做为字符串显示到浏览器地址栏!!!
彻底匹配,至关于 Route.exact。
严格匹配,至关于 Route.strict。
<Route>
多是 React Router 中最重要的组件,它能够帮助你理解和学习如何更好的使用 React Router。它最基本的职责是在其 path
属性与某个 location 匹配时呈现一些 UI。
请考虑如下代码:
import { BrowserRouter as Router, Route } from 'react-router-dom'; <Router> <div> <Route exact path="/" component={Home} /> <Route path="/news" component={News} /> </div> </Router>
若是应用程序的位置是 /
,那么 UI 的层次结构将会是:
<div> <Home /> <!-- react-empty: 2 --> </div>
或者,若是应用程序的位置是 /news
,那么 UI 的层次结构将会是:
<div> <!-- react-empty: 1 --> <News /> </div>
其中 react-empty
注释只是 React 空渲染的实现细节。但对于咱们的目的而言,它是有启发性的。路由始终在技术上被“渲染”,即便它的渲染为空。只要应用程序的位置匹配 <Route>
的 path
,你的组件就会被渲染。
使用 <Route>
渲染一些内容有如下三种方式:
在不一样的状况下使用不一样的方式。在指定的 <Route>
中,你应该只使用其中的一种。请参阅下面的解释,了解为何有三个选项。大多数状况下你会使用 component
。
三种渲染方式都将提供相同的三个路由属性:
指定只有当位置匹配时才会渲染的 React 组件,该组件会接收 route props 做为属性。
const User = ({ match }) => { return <h1>Hello {match.params.username}!</h1> } <Route path="/user/:username" component={User} />
当你使用 component
(而不是 render
或 children
)时,Router 将根据指定的组件,使用 React.createElement
建立一个新的 React 元素。这意味着,若是你向 component
提供一个内联函数,那么每次渲染都会建立一个新组件。这将致使现有组件的卸载和新组件的安装,而不是仅仅更新现有组件。当使用内联函数进行内联渲染时,请使用 render
或 children
(见下文)。
使用 render
能够方便地进行内联渲染和包装,而无需进行上文解释的没必要要的组件重装。
你能够传入一个函数,以在位置匹配时调用,而不是使用 component
建立一个新的 React 元素。render
渲染方式接收全部与 component
方式相同的 route props。
// 方便的内联渲染 <Route path="/home" render={() => <div>Home</div>} /> // 包装 const FadingRoute = ({ component: Component, ...rest }) => ( <Route {...rest} render={props => ( <FadeIn> <Component {...props} /> </FadeIn> )} /> ) <FadingRoute path="/cool" component={Something} />
警告:<Route component>
优先于<Route render>
,所以不要在同一个<Route>
中同时使用二者。
有时候不论 path
是否匹配位置,你都想渲染一些内容。在这种状况下,你可使用 children
属性。除了不管是否匹配它都会被调用之外,它的工做原理与 render
彻底同样。
children
渲染方式接收全部与 component
和 render
方式相同的 route props,除非路由与 URL 不匹配,不匹配时 match
为 null
。这容许你能够根据路由是否匹配动态地调整用户界面。以下所示,若是路由匹配,咱们将添加一个激活类:
const ListItemLink = ({ to, ...rest }) => ( <Route path={to} children={({ match }) => ( <li className={match ? 'active' : ''}> <Link to={to} {...rest} /> </li> )} /> ) <ul> <ListItemLink to="/somewhere" /> <ListItemLink to="/somewhere-else" /> </ul>
这对动画也颇有用:
<Route children={({ match, ...rest }) => ( {/* Animate 将始终渲染,所以你能够利用生命周期来为其子元素添加进出动画 */} <Animate> {match && <Something {...rest} />} </Animate> )} />
警告:<Route component>
和<Route render>
优先于<Route children>
,所以不要在同一个<Route>
中同时使用多个。
能够是 path-to-regexp 可以理解的任何有效的 URL 路径。
<Route path="/users/:id" component={User} />
没有定义 path
的 <Route>
老是会被匹配。
若是为 true
,则只有在 path
彻底匹配 location.pathname
时才匹配。
<Route exact path="/one" component={OneComponent} />
若是为 true
,则具备尾部斜杠的 path
仅与具备尾部斜杠的 location.pathname
匹配。当 location.pathname
中有附加的 URL 片断时,strict
就没有效果了。
<Route strict path="/one/" component={OneComponent} />
警告:可使用strict
来强制规定location.pathname
不能具备尾部斜杠,可是为了作到这一点,strict
和exact
必须都是true
。
通常状况下,<Route>
尝试将其 path
与当前历史位置(一般是当前的浏览器 URL)进行匹配。可是,也能够传递具备不一样路径名的位置进行匹配。
当你须要将 <Route>
与当前历史位置之外的 location
进行匹配时,此功能很是有用。如过渡动画示例中所示。
若是一个 <Route>
被包含在一个 <Switch>
中,而且须要匹配的位置(或当前历史位置)传递给了 <Switch>
,那么传递给 <Route>
的 location
将被 <Switch>
所使用的 location
覆盖。
若是为 true
,进行匹配时将区分大小写。
<Route sensitive path="/one" component={OneComponent} />
全部 Router 组件的通用低阶接口。一般状况下,应用程序只会使用其中一个高阶 Router:
使用低阶 <Router> 的最多见用例是同步一个自定义历史记录与一个状态管理库,好比 Redux 或 Mobx。请注意,将 React Router 和状态管理库一块儿使用并非必需的,它仅用于深度集成。
import { Router } from 'react-router-dom'; import createBrowserHistory from 'history/createBrowserHistory'; const history = createBrowserHistory(); <Router history={history}> <App /> </Router>
用于导航的历史记录对象。
import createBrowserHistory from 'history/createBrowserHistory'; const customHistory = createBrowserHistory(); <Router history={customHistory} />
要呈现的单个子元素(组件)。
<Router> <App /> </Router>
一个永远不会改变位置的 <Router>
。
这在服务器端渲染场景中很是有用,由于用户实际上没有点击,因此位置实际上并未发生变化。所以,名称是 static
(静态的)。当你只须要插入一个位置,并在渲染输出上做出断言以便进行简单测试时,它也颇有用。
如下是一个示例,node server 为 <Redirect>
发送 302 状态码,并为其它请求发送常规 HTML:
import { createServer } from 'http'; import React from 'react'; import ReactDOMServer from 'react-dom/server'; import { StaticRouter } from 'react-router'; createServer((req, res) => { // 这个 context 对象包含了渲染的结果 const context = {}; const html = ReactDOMServer.renderToString( <StaticRouter location={req.url} context={context}> <App /> </StaticRouter> ); // 若是使用 <Redirect>,context.url 将包含要重定向到的 URL if (context.url) { res.writeHead(302, { Location: context.url }); res.end(); } else { res.write(html); res.end(); } }).listen(3000);
全部位置的基准 URL。basename
的正确格式是前面有一个前导斜杠,但不能有尾部斜杠。
<StaticRouter basename="/calendar"> <Link to="/today" /> </StaticRouter>
上例中的 <Link>
最终将被呈现为:
<a href="/calendar/today" />
服务器收到的 URL,多是 node server 上的 req.url
。
<StaticRouter location={req.url}> <App /> </StaticRouter>
一个形如 {pathname, search, hash, state}
的位置对象。
<StaticRouter location={{ pathname: '/bubblegum' }}> <App /> </StaticRouter>
一个普通的 JavaScript 对象。在渲染过程当中,组件能够向对象添加属性以存储有关渲染的信息。
const context = {}; <StaticRouter context={context}> <App /> </StaticRouter>
当一个 <Route>
匹配时,它将把 context 对象传递给呈现为 staticContext
的组件。查看服务器渲染指南以获取有关如何自行完成此操做的更多信息。
渲染以后,可使用这些属性来配置服务器的响应。
if (context.status === '404') { // ... }
要呈现的单个子元素(组件)。
用于渲染与路径匹配的第一个子 <Route>
或 <Redirect>
。
这与仅仅使用一系列 <Route>
有何不一样?
<Switch>
只会渲染一个路由。相反,仅仅定义一系列 <Route>
时,每个与路径匹配的 <Route>
都将包含在渲染范围内。考虑以下代码:
<Route path="/about" component={About} /> <Route path="/:user" component={User} /> <Route component={NoMatch} />
若是 URL 是 /about
,那么 <About>
、<User>
和 <NoMatch>
将所有渲染,由于它们都与路径匹配。这是经过设计,容许咱们以不少方式将 <Route>
组合成咱们的应用程序,例如侧边栏和面包屑、引导标签等。
可是,有时候咱们只想选择一个 <Route>
来呈现。好比咱们在 URL 为 /about
时不想匹配 /:user
(或者显示咱们的 404 页面),这该怎么实现呢?如下就是如何使用 <Switch>
作到这一点:
import { Switch, Route } from 'react-router'; <Switch> <Route exact path="/" component={Home} /> <Route path="/about" component={About} /> <Route path="/:user" component={User} /> <Route component={NoMatch} /> </Switch>
如今,当咱们在 /about
路径时,<Switch>
将开始寻找匹配的 <Route>
。咱们知道,<Route path="/about" />
将会被正确匹配,这时 <Switch>
会中止查找匹配项并当即呈现 <About>
。一样,若是咱们在 /michael
路径时,那么 <User>
会呈现。
这对于动画转换也颇有用,由于匹配的 <Route>
与前一个渲染位置相同。
<Fade> <Switch> {/* 这里只会渲染一个子元素 */} <Route /> <Route /> </Switch> </Fade> <Fade> <Route /> <Route /> {/* 这里老是会渲染两个子元素,也有多是空渲染,这使得转换更加麻烦 */} </Fade>
用于匹配子元素而不是当前历史位置(一般是当前的浏览器 URL)的 location 对象。
全部 <Switch>
的子元素都应该是 <Route>
或 <Redirect>
。只有第一个匹配当前路径的子元素将被呈现。
<Route>
组件使用 path
属性进行匹配,而 <Redirect>
组件使用它们的 from
属性进行匹配。没有 path
属性的 <Route>
或者没有 from
属性的 <Redirect>
将始终与当前路径匹配。
当在 <Switch>
中包含 <Redirect>
时,你可使用任何 <Route>
拥有的路径匹配属性:path
、exact
和 strict
。from
只是 path
的别名。
若是给 <Switch>
提供一个 location
属性,它将覆盖匹配的子元素上的 location
属性。
<Switch> <Route exact path="/" component={Home} /> <Route path="/users" component={Users} /> <Redirect from="/accounts" to="/users" /> <Route component={NoMatch} /> </Switch>