React-Router-API中文介绍
React-Router API
以下内容翻译自react-router/doc/API.md,方便使用时查看,之前的学习都是能够工作即可,但一些内在发生的行为并不知晓,借此理解一番:
##Components
### `<Router>`
React Router的主要组件。 它可以让您的UI和网址保持同步。
#### Props
##### `children` (required)
一个或多个[`<Route>`](#route)或[`PlainRoute`](#plainroute)。 当历史变化时,`<Router>`将匹配其路由的一个分支,然后渲染其配置的[组件](#routecomponent),子路由组件嵌套在父节点内。
##### `routes`
`children`的别名
##### `history`
路由器监听的历史。 通常是`browserHistory`或`hashHistory`。
```js代码
import { browserHistory } from 'react-router'
ReactDOM.render(<Router history={browserHistory} />, el)
```
##### `createElement(Component, props)`
当路由器准备渲染路由组件的分支时,它将使用此功能创建元素。 当您使用某种数据抽象时,您可能需要控制创建元素,例如设置对存储的订阅,或者通过props将某种应用程序模块传递给每个组件。
```js代码
<Router createElement={createElement} /> //默认行为 function createElement(Component, props) { // 确保通过所有的props! return <Component {...props} /> } //或许你正在使用Relay function createElement(Component, props) { // 确保通过所有的props! return <RelayContainer Component={Component} routerProps={props} /> }
```
##### `onError(error)`
当路由器匹配时,错误可能会发生,这里是抓住并处理错误的机会。 通常这些将来自异步功能,如[`route.getComponents`](#getcomponentsnextstate-callback),[`route.getIndexRoute`](#getindexroutepartialnextstate-callback)和[`route.getChildRoutes`](#getchildroutespartialnextstate-callback)。
##### `onUpdate()`
当路由器更新其状态以响应URL更改时调用。
##### `render(props)`
这主要用于与在渲染路由组件之前需要参与渲染的其他库进行集成。 它默认为`render = {(props)=> <RouterContext {... props} />}`。
确保在行末尾渲染一个`<RouterContext>`,传递所有传递给`render`的props。
### `<Link>`
允许用户围绕您的应用程序浏览的主要方式。 `<Link>`将使用适当的href渲染一个完全可访问的<a>标签。
一个`<Link>`可以知道它链接到的路由何时是活动的,并且在给定一个prop时自动应用一个“activeClassName”和/或“activeStyle”。
如果当前路由是链接路由或链接路由的任何后代,则“<Link>”将被激活。 要使链接仅在确切链接的路由上处于活动状态,请使用[`<IndexLink>`](#indexlink)或设置“onlyActiveOnIndex”参数。
#### Props
##### `to`
如果它是一个字符串,它表示链接到的绝对路径,例如。 `/ users / 123`(不支持相对路径)。
如果它是一个对象,它可以有四个key:
`*`pathname`:表示链接到的路径的字符串。
*`query`:key对象:要对其进行字符串化的值对。
*`hash`:要放入URL的哈希,例如`#A-hash`。
*`state`:状态持续到`location`。
如果未指定,将不呈现不带“href”属性的<a>标签。
_注意:React Router当前不支持滚动到锚点位置,不会滚动到与`hash`._对应的元素
##### `activeClassName`
当路由处于活动状态时使用,没有默认值。
##### `activeStyle`
当路由活动时应用于链接元素的样式。
##### `onClick(e)`
点击事件的自定义处理程序。 工作就像一个`<a>`标签上的处理程序 - 调用`e.preventDefault()`将阻止转换触发,而`e.stopPropagation()`将会阻止事件冒泡。
##### `onlyActiveOnIndex`
如果为“true”,则当前路由与链接路由完全匹配时,“<Link>”会处于活动状态。
##### *others*
你也可以把你想要的paops放在`title`, `id`, `className`等
```js代码
<Link to={`/users/${user.id}`} activeClassName="active">{user.name}</Link> // 根据您的历史记录,如果该路由是活动的,类名将标记 active <a href="/users/123" class="active">Michael</a> <a href="#/users/123">Michael</a> // 更改 activeClassName <Link to={`/users/${user.id}`} activeClassName="current">{user.name}</Link> //activeStyle使用 <Link to="/users" style={{color: 'white'}} activeStyle={{color: 'red'}}>Users</Link>
```
### `<IndexLink>`
``IndexLink>`就像一个[`<Link>`](#link),只有当当前路由完全是链接路由才有效。 它相当于`<Link>`与`onlyActiveOnIndex`支持集合。
### `withRouter(Component, [options])`
一个HoC(高阶分量),包裹另一个组件来提供`props.router`。 传入您的组件,它将返回包装的组件。
您可以明确指定“路由器”作为包装器组件的支持,以从上下文覆盖路由器对象。
#### Options
##### `withRef`
如果为“true”,则包装器组件将引用附加到包装的组件,然后可以通过“getWrappedInstance”访问。
```js代码
const WrapperComponent = withRouter(MyComponent, { withRef: true }) // 给定一个类型为“WrapperComponent”的`wrapperInstance`: const myInstance = wrapperInstance.getWrappedInstance()
```
### `<RouterContext>`
`<RouterContext>'为给定的路由器状态呈现组件树。 它被`<Router>`使用,也可用于服务器呈现和集成在brownfield开发中。
#### `context.router`
包含与路由相关的数据和方法。 最有用的应用程序的强制性过渡。
##### `push(pathOrLoc)`
转换到新的URL,在浏览器历史记录中添加一个新记录。
```js代码
router.push('/users/12') router.push({ pathname: '/users/12', query: { modal: true }, state: { fromDashboard: true } })
```
##### `replace(pathOrLoc)`
与“push”相同,用新的历史条目替换当前的历史记录。
##### `go(n)`
在“n”或“-n”的历史中向前或向后。
##### `goBack()`
回到上一个历史记录。
##### `goForward()`
在历史上前进一个。
##### `setRouteLeaveHook(route, hook)`
注册给定的钩子函数在路由离开给定路径之前运行。
在正常转换期间,挂钩功能将接收下一个位置作为其唯一的参数,并且可以返回提示消息(字符串)来提示用户,以确保他们要离开页面; 或“不离开”,以防止过渡。 任何其他返回值都不起作用。
在beforeunload事件期间(在浏览器中),钩子不接收参数。
在这种情况下,它必须返回提示信息以防止转换。
返回可用于取消绑定侦听器的函数。
在大多数情况下,您不需要手动拆除路由挂钩。 离开相关路线后,我们会自动删除所有附加的路线假挂钩。
##### `createPath(pathOrLoc, query)`
使用路由器的配置将查询字符串添加到路径名中。
##### `createHref(pathOrLoc, query)`
使用路由器的配置创建一个URL。 例如,它将在`pathname`前面添加`#/`用于哈希历史记录。
##### `isActive(pathOrLoc, indexOnly)`
根据“pathOrLoc”是否处于活动状态,返回“true”或“false”。 路由分支中的每个路由匹配(子路由处于活动状态,因此父对象也是如此),除非指定了“indexOnly”,否则将只匹配确切的路径。
如果所有URL参数匹配,路由才被视为活动的,包括可选参数及其存在或不存在。
但是,只会明确指定查询参数。 这意味着当位置为`/ foo?a = b&c = d`时,`isActive({pathname:'/ foo',query:{a:'b'}}))将返回`true`。 要求不存在查询参数,请将其值指定为显式的“未定义”,例如。 `isActive({pathname:'/ foo',query:{a:'b',c:undefined}})`,在这个例子中这将是`false`。
## Configuration Components
### `<Route>`
`<Route>` 用于声明性地将路由映射到应用程序组件层次结构
#### Props
##### `path`
URL中使用的路径。
它将与父路由的路径连接,除非以`/`开头,使其成为绝对的路径。
如果未定义,路由器将尝试匹配子路由。
##### `component`
当路由与URL匹配时要呈现的单个组件。 它可以由父路由组件呈现为`this.props.children`。
```js
const routes = ( <Route path="/" component={App}> <Route path="groups" component={Groups} /> <Route path="users" component={Users} /> </Route> ) class App extends React.Component { render () { return ( <div> {/* this will be either <Users> or <Groups> */} {this.props.children} </div> ) } }
```
##### `components`
路由可以将一个或多个命名组件定义为当路径与URL匹配时要呈现的[名称]:组件对的对象。 它们可以由父路由组件用`this.props [name]`呈现。
```js
// 想想它在路由器的上下文之外 - 如果你有`render`的可插拔部分,你可能会这样做: // <App main={<Users />} sidebar={<UsersSidebar />} /> const routes = ( <Route path="/" component={App}> <Route path="groups" components={{main: Groups, sidebar: GroupsSidebar}} /> <Route path="users" components={{main: Users, sidebar: UsersSidebar}}> <Route path=":userId" component={Profile} /> </Route> </Route> ) class App extends React.Component { render () { const { main, sidebar } = this.props return ( <div> <div className="Main"> {main} </div> <div className="Sidebar"> {sidebar} </div> </div> ) } } class Users extends React.Component { render () { return ( <div> {/* if at "/users/123" `children` will be <Profile> */} {/* UsersSidebar will also get <Profile> as this.props.children, so its a little weird, but you can decide which one wants to continue with the nesting */} {this.props.children} </div> ) } }
```
##### `getComponent(nextState, callback)`
与“component”相同,是异步的,对代码分解很有用。
###### `callback` 签名
`cb(err, components)`
```js代码
<Route path="courses/:courseId" getComponents={(nextState, cb) => { // do asynchronous stuff to find the components cb(null, {sidebar: CourseSidebar, content: Course}) }} />
```
##### `children`
路由可以嵌套,`this.props.children`将包含从子路由组件创建的元素。
##### `onEnter(nextState, replace, callback?)`
当路径即将被输入时调用。 它提供下一个路由器状态和一个重定向到另一个路径的功能。 `this`将是触发钩子的路由实例。
如果“callback”被列为第三个参数,则该钩子将异步运行,并且转换将阻塞,直到调用“callback”为止。
###### `callback` signature
`cb(err)`
```js
const userIsInATeam = (nextState, replace, callback) => { fetch(...) .then(response = response.json()) .then(userTeams => { if (userTeams.length === 0) { replace(`/users/${nextState.params.userId}/teams/new`) } callback(); }) .catch(error => { // do some error handling here callback(error); }) } <Route path="/users/:userId/teams" onEnter={userIsInATeam} />
```
##### `onChange(prevState, nextState, replace, callback?)`
当位置发生变化时,路由器被呼叫,但路由本身既不进入也不进入。 例如,当路由的子节点更改或位置查询更改时,将会调用此方法。 它提供以前的路由器状态,下一个路由器状态和一个重定向到另一个路径的功能。 `this`将是触发钩子的路由实例。
如果“callback”被列为第四个参数,则该钩子将异步运行,并且转换将阻塞,直到调用“callback”为止。
##### `onLeave(prevState)`
当前路径即将退出时调用。
### `PlainRoute`
一个简单的JavaScript对象路由定义。 `<Router>`将JSX`<Route>`转换成这些对象,但是如果你愿意,你可以直接使用它们。 所有props与“<Route>”props相同,但这些props除外。
#### Props
##### `childRoutes`
一组子路由,与JSX路由配置中的“children”相同。
##### `getChildRoutes(partialNextState, callback)`
与`childRoutes`相同但是异步并且接收`partialNextState`。 适用于代码分割和动态路由匹配(给定一些状态或会话数据以返回不同的一组子路由)。
###### `callback` signature
`cb(err, routesArray)`
```js
let myRoute = { path: 'course/:courseId', childRoutes: [ announcementsRoute, gradesRoute, assignmentsRoute ] } // async child routes let myRoute = { path: 'course/:courseId', getChildRoutes(location, cb) { // do asynchronous stuff to find the child routes cb(null, [ announcementsRoute, gradesRoute, assignmentsRoute ]) } } // navigation dependent child routes // can link with some state <Link to="/picture/123" state={{ fromDashboard: true }} /> let myRoute = { path: 'picture/:id', getChildRoutes(partialNextState, cb) { let { state } = partialNextState if (state && state.fromDashboard) { cb(null, [dashboardPictureRoute]) } else { cb(null, [pictureRoute]) } } }
```
##### `indexRoute`
这与在使用JSX路由配置时指定“<IndexRoute>”子代相同。
##### `getIndexRoute(partialNextState, callback)`
与`indexRoute`相同,但是异步并接收`partialNextState`。 与`getChildRoutes`一样,这对于代码分割和动态路由匹配是有用的。
###### `callback` signature
`cb(err, route)`
```js
let myIndexRoute = { component: MyIndex } let myRoute = { path: 'courses', indexRoute: myIndexRoute } // async index route let myRoute = { path: 'courses', getIndexRoute(partialNextState, cb) { // do something async here cb(null, myIndexRoute) } }
```
### `<Redirect>`
`<Redirect>`设置重定向到应用程序中的另一个路由,以维护旧的URL。
#### Props
##### `from`
要重定向的路径,包括动态段。
##### `to`
要重定向到的路径。
##### `query`
默认情况下,查询参数将通过,但如果需要,您可以指定它们。
```js
// Say we want to change from `/profile/123` to `/about/123` // and redirect `/get-in-touch` to `/contact` <Route component={App}> <Route path="about/:userId" component={UserProfile} /> {/* /profile/123 -> /about/123 */} <Redirect from="profile/:userId" to="about/:userId" /> </Route>
```
请注意,只要规则适用,可以将`<Redirect>`放置在路由层次结构中的任何位置。 如果您希望重定向在其各自的路由旁边,则`from`路径将与正常路由“路径”相同。
```js
<Route path="course/:courseId"> <Route path="dashboard" /> {/* /course/123/home -> /course/123/dashboard */} <Redirect from="home" to="dashboard" /> </Route>
```
### `<IndexRoute>`
当访问者位于父级的URL时,“<IndexRoute>”可以让您为父路由提供默认的“child”。
#### Props
All the same props as [Route](#route) except for `path`.
所有与[Route](#route)相同的props,除了“path”。
### `<IndexRedirect>`
“<IndexRedirect>”可以让您从父路由的URL重定向到另一个路由。 它们可用于允许子路由作为其父级的默认路由,同时仍保留不同的URL。
#### Props
所有与[Redirect](#redirect)相同的道具,除了“from”。
## Route Components
当该路由与URL匹配时,将渲染路由的组件。 渲染时,路由器会将以下属性注入到组件中:
### Injected Props
#### `location`
#### `params`
网址的动态细分。
#### `route`
渲染此组件的路由。
#### `routeParams`
在该组件的路由中直接指定的“this.props.params”的子集。 例如,如果路由的路径是“users /:userId”,URL是`/ users / 123 / portfolios / 345`,那么`this.props.routeParams`将是`{userId:'123'}` this.props.params`将是`{userId:'123',portfolioId:'345'}`。
#### `children`
要呈现的匹配子路由元素。 如果路由具有[命名组件](/ docs / API.md#named-components),那么这将是未定义的,组件将作为直接属性可用于`this.props`。
##### Example
```js
render(( <Router> <Route path="/" component={App}> <Route path="groups" component={Groups} /> <Route path="users" component={Users} /> </Route> </Router> ), node) class App extends React.Component { render() { return ( <div> {/* this will be either <Users> or <Groups> */} {this.props.children} </div> ) } }
```
#### `history` (弃用)
### Named Components
当路由具有一个或多个命名组件时,子元素可以通过`this.props`上的名称使用。 在这种情况下,`this.props.children`将是未定义的。 所有路由组件都可以参与嵌套。
#### Example
```js
render(( <Router> <Route path="/" component={App}> <Route path="groups" components={{main: Groups, sidebar: GroupsSidebar}} /> <Route path="users" components={{main: Users, sidebar: UsersSidebar}}> <Route path="users/:userId" component={Profile} /> </Route> </Route> </Router> ), node) class App extends React.Component { render() { // the matched child route components become props in the parent return ( <div> <div className="Main"> {/* this will either be <Groups> or <Users> */} {this.props.main} </div> <div className="Sidebar"> {/* this will either be <GroupsSidebar> or <UsersSidebar> */} {this.props.sidebar} </div> </div> ) } } class Users extends React.Component { render() { return ( <div> {/* if at "/users/123" this will be <Profile> */} {/* UsersSidebar will also get <Profile> as this.props.children. You can pick where it renders */} {this.props.children} </div> ) } }
```
## Histories
### `browserHistory`
`browserHistory`可用时使用HTML5历史记录API,否则返回到完全刷新。 `browserHistory`需要在服务器端进行额外的配置才能提供URL,但是现代网页通常是首选解决方案。
### `hashHistory`
`hashHistory`使用URL哈希,连同一个查询键来跟踪状态。 `hashHistory`不需要额外的服务器配置,但通常不如`browserHistory`优先。
### `createMemoryHistory([options])`
`createMemoryHistory`创建一个不与浏览器URL进行交互的内存中的`history`对象。 当您需要自定义用于服务器端呈现的“history”对象,用于自动测试时,或者当您不想操作浏览器URL时,例如将应用程序嵌入到“<iframe”中时,这是非常有用的>`。
### `useRouterHistory(createHistory)`
`useRouterHistory`是一个`history`增强器,用于配置给定的`createHistory`工厂来与React Router配合工作。 除了捆绑的单例历史之外,还允许使用自定义历史。
#### Example
```js
import createHashHistory from 'history/lib/createHashHistory' const history = useRouterHistory(createHashHistory)({ queryKey: false })
```
## Utilities
### `match({ routes, location, [history], [...options] }, cb)`
此功能用于服务器端呈现。 它将一组路由匹配到一个位置,而不渲染,并在完成后调用`callback(error,redirectLocation,renderProps)'。
该函数将为您创建一个“历史”,传递附加的“选项”以创建它。 这些选项可以包括“basename”来控制URL的基本名称,以及一对`parseQueryString`和`stringifyQuery'来控制查询字符串解析和序列化。 您也可以传入一个已经实例化的“历史”对象,可以根据需要构建它。
传递给`match`的回调函数的三个参数是:
- `error`:如果发生错误,则为JavaScript`Error`对象,否则为'undefined`。
- `redirectLocation`:A [Location](/ docs / Glossary.md#location)对象,如果路由是重定向,`undefined`否则。
- `renderProps`:如果路由匹配,你应该传递给路由上下文的道具,否则为'undefined`。
如果所有三个参数都是“undefined”,这意味着没有找到匹配给定位置的路由。
*注意:您可能不想在浏览器中使用它,除非您正在进行异步路由的服务器端渲染。
### `createRoutes(routes)`
从给定的对象创建并返回一个路由数组,该对象可能是一个JSX路由,一个普通对象路由或者一个数组。
#### params
##### `routes`
### `PropTypes`
以下支持类型在顶层导出,并从“react-router / lib / PropTypes”导出:
- `routerShape`:上下文中`router`对象的形状
- “locationShape”:路由组件道具上的“location”对象的形状
以前,一些用于内部使用的支撑类型也在“PropTypes”下导出。 这些不推荐使用,不应该使用。