React-Router

React-Router

React Router 中有三种类型的组件: router components, route matching components,和 navigation components。

React-router-dom

router components

<Router>

Router 是所有路由组件共用的底层接口。通常,我们的应用程序将使用其中一个高级路由器代替:

  • <BrowserRouter>
  • <HashRouter>
  • <MemoryRouter>
  • <NativeRouter>
  • <StaticRouter>

最常见的使用底层的 的情形就是用来与 Redux 或者 Mobx 之类的状态管理库的定制的 history 保持同步。注意不是说使用状态管理库就必须使用 React Router ,它仅用作于深度集成。

<BrowserRouter>

<HashRouter>

<MemoryRouter>

<NativeRouter>

<StaticRouter>

route matching components

Route

没有路径总会匹配挂载,如果不需要请用Switch

以下所有的三种渲染方法都会通过三个相同的Route属性

  • match
  • location
  • history

history

本文档中的 “history” 以及 “history对象”指的是 history 包中的内容,该包是 React Router 仅有的两大主要依赖之一(除去 React 本身),在不同的 Javascript 环境中,它提供多种不同的形式来实现对 session 历史的管理。

history 对象通常会具有以下属性和方法:

  • length (number 类型) history 堆栈的条目数
  • action (string 类型) 当前的操作(PUSH, REPLACE, POP)
  • location (object 类型) 当前的位置。location 会具有以下属性:
    • pathname (string 类型) URL 路径
    • search (string 类型) URL 中的查询字符串
    • hash (string 类型) URL 的哈希片段
    • state (object 类型) 提供给例如使用 push(path, state) 操作将 location 放入堆栈时的特定 location 状态。只在浏览器和内存历史中可用。
  • push(path, [state]) 在 history 堆栈添加一个新条目
  • replace(path, [state]) 替换在 history 堆栈中的当前条目
  • go(n) 将 history 堆栈中的指针调整 n
  • goBack() 等同于 go(-1)
  • goForward() 等同于 go(1)
  • block(prompt) 阻止跳转。(详见 history 文档)。

history 是可变的,因此我们建议从 <Route> 的渲染选项中来访问 location,而不是从 history.location 直接获取。这样做可以保证 React 在生命周期中的钩子函数正常执行,例如:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
class Comp extends React.Component {
  componentWillReceiveProps(nextProps) {
    // locationChanged 将为 true
    const locationChanged = nextProps.location !== this.props.location

    // INCORRECT,因为 history 是可变的所以 locationChanged 将一直为 false
    const locationChanged = nextProps.history.location !== this.props.history.location
  }
}

<Route component={Comp}/>

location

location 代表应用程序现在在哪,你想让它去哪,或者甚至它曾经在哪,它看起来就像:

1
2
3
4
5
6
7
8
9
{
  key: 'ac3df4', // not with HashHistory!
  pathname: '/somewhere'
  search: '?some=search-string',
  hash: '#howdy',
  state: {
    [userDefined]: true
  }
}

router 将在这几个地方为您提供一个 location 对象:

  • Route component as this.props.location
  • Route render as ({ location }) => ()
  • Route children as ({ location }) => ()
  • withRouter as this.props.location

它也可以在 history.location 找到,但是你不应该使用它,因为它是可变的,你可以在 history 文档中阅读更多内容。

location 对象永远不会发生变化,因此你可以在生命周期钩子中使用它来确定何时导航,这对数据抓取和动画非常有用。

1
2
3
4
5
componentWillReceiveProps(nextProps) {
  if (nextProps.location !== this.props.location) {
    // navigated!
  }
}

你可以将 location 而不是字符串提供给导航的各种位置:

  • Web Link to
  • Native Link to
  • Redirect to
  • history.push
  • history.replace

通常你只是使用一个字符串,但是如果你需要添加一些 “location state”,只要应用程序返回到特定的地址就可以使用,你可以使用 location 对象。 如果你想根据导航历史记录而不是仅路径(比如模式)来分支UI,这很有用。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
// usually all you need
<Link to="/somewhere"/>

// but you can use a location instead
const location = {
  pathname: '/somewhere',
  state: { fromDashboard: true }
}

<Link to={location}/>
<Redirect to={location}/>
history.push(location)
history.replace(location)

最后,你可以将 location 传递给以下组件:

  • Route
  • Switch

这将阻止他们在 router 的状态下使用实际的 location。这对动画和在等待的导航非常有用,或者任何时候你想哄骗一个组件在不同的 location 渲染到真实的位置。

match

一个 match 对象中包涵了有关如何匹配 URL 的信息。match 对象中包涵以下属性:

  • params - (object) key/value 与动态路径的 URL 对应解析
  • isExact - (boolean) true 如果匹配整个 URL (没有结尾字符)
  • path - (string) 用于匹配的路径模式。被嵌套在 <Route> 中使用
  • url - (string) 用于匹配部分的 URL 。被嵌套在 <Link> 中使用

你将会在这些地方用到 match 对象:

  • Route component 例如 this.props.match
  • Route render 例如 ({ match }) => ()
  • Route children 例如 ({ match }) => ()
  • withRouter 例如 this.props.match
  • matchPath 例如 返回值

如果 Route 没有 path,那么将会一直与他最近的父级匹配。这也同样适用于withRouter。

null matches

当前路由的 path 与当前地址不匹配时,使用 children 属性的 <Route> 将调用 children 方法。这种情况下, match 将为 null 。当 <Route> 中的内容能够被渲染出来时,说明匹配成功,但这种情况是有挑战性的。

“解析”URL的默认方式是将 match.url 字符串连接到“相对”路径。

${match.url}/relative-path

如果你的匹配为 null 时尝试执行此操作,则会出现TypeError。它的意思是在使用子级属性时在 <Route> 内部加入“相对”路径是不安全的。

当您在生成null匹配对象的 <Route> 内部使用无路径的 <Route> 时。会出现类似但更微妙的情况。

1
2
3
4
5
6
7
// location.pathname = '/matches'
<Route path='/does-not-match' children={({ match }) => (
  // match === null
  <Route render={({ match:pathlessMatch }) => (
    // pathlessMatch === ???
  )}/>
)}/>

无路径的 从它们的父节点继承它们的match对象。 如果他们的父match是null,那么他们的匹配也是null。 这意味着:a)任何子路由/链接必须是绝对的,因为没有父级去解决,并且b)父级路径match可以是null的无路径路由将需要使用子级属性进行渲染。


component props

参数是一个组件

render props

参数是一个函数 props => <Component {...props} extra={someVariable} />

children props

Switch

返回第一个匹配的路由

React Router 提供了一个 <Link> 组件来在你的应用程序中创建链接。无论你在何处渲染一个 <Link> ,都会在应用程序的 HTML 中渲染锚 (<a>)。

<NavLink> 是一种特殊类型的 <Link> 当它的 to 属性与当前地址匹配时,可以将其定义为“活跃的”。

1
2
3
4
5
// location = { pathname: '/react' }
<NavLink to="/react" activeClassName="hurray">
  React
</NavLink>
// <a href='/react' className='hurray'>React</a>

Redirect

当你想强制导航时,你可以渲染一个 <Redirect>。当一个 <Redirect> 渲染时,它将使用它的 to 属性进行定向。

Licensed under CC BY-NC-SA 4.0
最后更新于 Aug 14, 2024 09:45 UTC