React 初探(十一)
概述
之前已经将目录构建完成,这次主要将路由和页面结合起来,完成一些路由的切换和页面的跳转。我的项目地址
<BrowserRouter> 与 <HashRouter>
在之前的文章中已经说明了 hash
与 history
实现路由的方式,在 React-Router
中也有两种模式,即 <BrowserRouter>
和 <HashRouter>
<BrowserRouter>
<Router>
使用 HTML5 history
API( pushState
、replaceState
和 propsState
事件 )去保持你的 UI 和 URL
同步
属性:
-
basename
: string -> 所有location
的基本URL
。如果你的应用程序是从服务器上的子目录提供服务的,你需要将其设置为子目录。正确格式的basename
应该有一个前导斜杠,并且没有尾随斜杠 -
getUserConfirmation
: Function -> 用于确认导航的功能,默认为使用window.confirm
-
forceRefresh
: Boolean -> 如果为true
,路由将会在页面导航中使用整个刷新。你可能只希望在不支持 HTML5history
API 的浏览器中使用它 -
keyLength
: Number ->location.key
的length
,默认是6 -
children
: node ->render
单个子元素
<HashRouter>
<Router>
使用 URL
的 hash
部分( window.location.hash ) 去保持你的 UI 和 URL
同步
注意:hash
历史不支持 location.key
或者 location.state
。在以前的版本中,我们试图填充行为,但是有一些边缘情况不能解决。任何需要此行为的代码或插件都不能工作。由于此技术仅用于支持传统浏览器,因此建议使用 <BrowserRouter>
最佳实践
使用 <BrowserRouter>
Link + Route 实现路由跳转
可以通过 react-router
的 <Link>
+ <Route>
实现路由跳转。
<BrowserRouter>
<div className="router">
<button className="link-button"><Link to="/">Home</Link></button>
<button className="link-button"><Link to="/login">Login</Link></button>
<Route path="/" exact component={Home} />
<Route path="/login" exact component={Login} />
</div>
</BrowserRouter>
<Link>
引入
import { Link } from 'react-router-dom'
属性
-
to
: String -> 要链接的地址的字符串,通过连接的location
的pathname
、search
和hash
创建 -
to
: Object -> 可以具有以下任何属性的对象-
pathname
-> 一个字符串代表要去的路径(A string representing the path to link to.
) -
search
-> 一个字符串代表查询参数(A string representation of query parameters.
) -
hash
-> 一个hash
放在URL
中(A hash to put in the URL, e.g. #a-hash.
) -
state
-> 状态已保留到该位置(State to persist to the location.
)
-
-
replace
: Boolean -> 当该值为true
,点击这个link
时在history
栈中不会增加一个新的地址,而是会替代现在的地址 -
innerRef
: Function -> 允许访问组件的基础引用
<Route>
<Route>
组件在 React-Router
中可能是最重要的去理解和学习良好使用的组件,它最基本的职责是在位置和路由路径匹配时呈现一些 UI。一旦应用程序 location
和 路由路径匹配,你的组件将会被渲染
引入
import { Route } from 'react-router-dom'
属性
Router render methods
这里有三种方式去 render
通过 <Route>
<Route component>
<Route render>
<Route children>
每一个都是有用的在不同的环境中。你应该使用其中一种在给定的 <Route>
。查看他们的说明来理解为什么你有三个选项,大多数情况下你将会使用 component
component
-
渲染一个
React
组件只有当location
匹配时,他将被render
随着route props
-
当你使用
component
时,而不是下面的render
和children
,router
使用React.createElement
去创建一个新的React element
从给定的组件中,这意味着如果你给组件提供一个inline function
的props
,每次render
时你将会创建一个新的component
,这将导致现有的组件unmount
和新的组件mount
而不仅仅是更新现有组件。当使用inline function
进行inline render
时,使用下面的render
和children
属性
-
render
: Function
-
这样可以方便的进行
inline render
和wrapping
而无需上述不需要的重新安装 -
你可以传递一个函数,当
location
匹配的时候该函数将会被调用,而不是使用组件属性为您创建一个新的React element
。render
属性接收与component
属性相同的所有route props
注意: <Route component>
要优先于 <Route render>
所以不要在相同的 <Route>
中使用两者
3.children
: Function
-
有时你需要
render
路径是否与location
相匹配,在这些情况下,你可以使用children
属性。它的工作原理和render
相同,除了无论是否匹配它都会被调用 -
children
render 属性接收与component
和render
方法相同的route props
,除了当路由和URL
匹配失败时,match
是null
。这允许你动态调整你的 UI 根据路由是否匹配。这里,如果路由匹配我们将会添加一个active
类
注意:<Route component>
和 <Route render>
优先于 <Route children>
所以不要在相同的 <Route>
中使用两个或三个
Route props
所有的三个 render
方法将会具有三个相同的 route props
- match
- location
- history
-
path
: string | string[]
能够被解析的任何有效的URL
path
或者path
数组
Routes without a path always match.( 没有路径的路由总是匹配的 )
-
exact
: Boolean
如果为true
,则仅仅当path
和location.pathname
完全匹配时才匹配
path | location.pathname | exact | matches? |
---|---|---|---|
/one | /one/two | true | no |
/one | /one/two | false | yes |
-
strict
: Boolean
如果为true
,则带有尾随斜杠的路径将只与带有尾随斜杠的location.pathname
匹配,当location.pathname
中有其他URL
部分时这是不起作用的
path | location.pathname | matches? |
---|---|---|
/one/ | /one | no |
/one/ | /one/ | yes |
/one/ | /one/two | yes |
注意:strict
可以被用于强制 location.pathname
没有尾随斜杠,但是为了做这个 strict
和 exact
必须都是 true
path | location.pathname | matches? |
---|---|---|
/one | /one | yes |
/one | /one/ | no |
/one | /one/two | no |
-
location
: Object
<Route>
元素尝试将其路径去和当前历史位置location
匹配( 通常是当前浏览器 URL )。但是,也可以传递带有不同的pathname
的location
进行匹配。这是非常有用的假使当你需要将<Route>
匹配到当前历史以外的location
- 如果一个
<Route>
元素被包裹在一个<Switch>
中,并且与传递给<Switch>
的location
匹配( 或当前历史位置 )。那么传递给<Route>
的location
属性将被<Switch>
使用的属性覆盖
-
sensitive
: Boolean
如果为true
,路径匹配将区分大小写
path | location.pathname | sensitive | matches? |
---|---|---|---|
/one | /one | true | yes |
/One | /one | true | no |
/One | /one | false | yes |
history
+ <Router>
实现路由跳转代码
然而上述的 <Link>
+ <Route>
并不能满足我们的需求,例如我们有时需要点击一个 button
之后先进行一些逻辑操作,之后再进行跳转,这时我们需要使用 history
。
history
和 history object
指的是 history package
,它是 React Router
中的两个主要依赖项之一( 除了 React 本身 ),它提供了几种不同的实现方式,用于各种环境中来管理 JavaScript 中的会话 history
还使用以下术语:
-
browser history
-> 一种特定于 DOM 的实现,在支持 HTML5history
API 的 Web 浏览器中非常有用 -
hash history
-> 针对于传统 Web 浏览器的特定于 DOM 的实现 -
memory history
-> 内存中的历史实现,在测试和非 DOM 环境( 如 React native )中非常有用
属性 | 方法
-
length
: Number -> 历史记录堆栈中的条目数 -
action
: String -> 当前的操作(push
、replace
、pop
) -
location
: Object -> 当前的location
,可能含有下列属性:-
pathname
: String ->URL
的路径 -
search
: String ->URL
的query
字符串 -
hash
: String ->URL
的hash
片段 -
state
: Object -> 提供给特定未知的状态,例如,将此位置推送到堆栈时的推送( 路径、状态 )。仅在浏览器和内存历史记录中可用
-
-
push( path [, state] )
: Function -> 将新条目推送到历史堆栈中 -
replace( path [, state] )
: Function -> 替换历史堆栈上的当前条目 -
go( n )
: Function -> 将历史堆栈中的指针移动 n 个条目 -
goBack()
: Function -> 等同于go( -1 )
-
goForward()
: Function -> 等同于go( 1 )
-
block( prompt )
: Function -> 阻止导航
注意:history
对象是可变的。因此,建议从 <route>
的 render props
访问 location
,而不是从 history.location
,这可以确保您对 React 的假设在生命周期函数中是正确的。