React-Router

安装并引入

安装

npm install react-router-dom

引入

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

基本组件

React Router 中有三类组件:

  • router 组件(BrowserRouter, HashRouter)
  • route matching 组件(Route,Switch)
  • navigation 组件(Link,NavLink)

Router 组件

基于 React Router 的 Web 应用,其根组件应该是一个 router 组件(BrowserRouter,HashRouter)。项目中, react-router-dom 提供了两种路由,这两种路由都会创建一个 history 对象。如果我们的应用中有服务器响应 web 的请求,我们通常使用 <BrowserRouter> 组件,如果使用静态文件服务器,则我们应该使用 <HashRouter> 组件。

// 我们可以直接在 index 入口文件中引入 BrowserRouter 组件
import { BrowserRouter } from "react-router-dom";
ReactDOM.render(
  <BrowserRouter>
    <App />
  </BrowserRouter>,
  holder
);

路由匹配

react-router-dom中有两个匹配路由的组件:.

import { Route, Switch } from "react-router-dom";

路由匹配是通过将 Route 组件的 path 属性与当前的 locationpathname 进行比较来完成的。当一个 <Route> 与当前地址栏中的路径匹配了,那么它所对应的组件内容将被渲染出来;如果不匹配,则渲染 null。当一个 <Route> 没有 path 属性,那么它所对应的内容将总是会被渲染出来。

// 当 location = { pathname: '/about' }
<Route path='/about' component={About}/> // 路径匹配成功,渲染 <About/>组件
<Route path='/contact' component={Contact}/> // 路径不匹配,渲染 null
<Route component={Always}/> // 该组件没有path属性,其对应的<Always/>组件会一直渲染

我们可以在组件树的任何位置放置组件。但是更常见的情况是将几个写在一起。组件可以用来将多个“包裹”在一起。

多个组件在一起使用时,并不强制要求使用组件,但是使用组件却是非常便利的。会迭代它下面的所有子组件,并只渲染第一个路径匹配的

<Switch>
  <Route exact path="/" component={Home} />
  <Route path="/about" component={About} />
  <Route path="/contact" component={Contact} />
</Switch>

<Switch>
  <Route exact path="/" component={Home} />
  <Route path="/about" component={About} />
  <Route path="/contact" component={Contact} />
  {/* 如果上面的Route的路径都没有匹配上,则 <NoMatch>被渲染,我们可以在此组件中返回404 */}
  <Route component={NoMatch} />
</Switch>

Route 渲染属性

匹配时显示组件的写法,有以下三种:

component

在使用 时,如果我们想渲染的内容已经有对应的组件,则可以直接使用 component 属性渲染该组件。

<Route path="/user/:username" component={User} />;

function User({ match }) {
  return <h1>Hello {match.params.username}!</h1>;
}

render

render 属性能使我们便捷地渲染内联组件或者是嵌套组件,我们可以给这个属性传入一个函数,当路由的路径匹配时调用。同时,render 属性也会接受所有的 Route 传入的参数。

//内联方式
<Route path="path" render={() => <div>这是内联组件写法</div>} />
//嵌套组合方式
<Route path="path" render={ props => (
    <ParentComp>
        <Comp {...props} />
    </ParentComp>
) />

children

children 属性接收一个函数作为其值,当 Route 中有 children 属性时,不管当前的路径是否与 Route 匹配,该函数都会执行,同时,children 属性也会接收 Route 传入的所有的参数。

<Route path="path" children={ props => (
   <div className={props.match? "active": ''}>
         <Link to="path" />
     </div>
) />
	

注意: 不要将 component 属性设置为一个函数,然后在其内部渲染组件。这样会导致已经存在的组件被卸载,然后重写创建一个新的组件,而不是仅仅对组件进行更新。

注意

在使用 Route 的这三个属性渲染组件时,当三个属性同时存在会有优先级的问题,正常情况下使用其中的一个属性就可以,但是如果当他们同时存在,优先渲染 children 的值,其他的不会渲染;其次,如果 component 和 render 同时存在,那么会渲染 component,而不会渲染 render 属性。

children > component > render

React Router 提供了<Link> 组件用来在应用中添加跳转链接。 默认会被渲染为 a 标签。

<Link to="/">Home</Link>
// <a href='/'>Home</a>

<NavLink> 组件是一个特殊的 <Link> 组件。当它的 path与当前 location 匹配时,可以自定义其样式来表示当前页面位置。

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

Redirect 组件

当页面需要重定向时,我们可以使用 <Redirect> 组件。当一个 <Redirect> 组件被渲染时,页面将被渲染到 <Redirect> 组件的 to 属性指定的位置上。

// 如果是登录状态,则跳转到 dashboard 页面,否则是公共页面
<Route exact path="/" render={() => (
  loggedIn ? (
    <Redirect to="/dashboard"/>
  ) : (
    <PublicHomePage/>
  )
)}/>

使用 Switch 包裹和直接使用 Route 的区别?

<Switch> 渲染第一个被 location 匹配到的并且作为子元素的 <Route> 或者 <Redirect>

<Switch> 是唯一的,因为它仅仅只会渲染一个路径。相比之下,不使用 <Switch> 包裹的情况下,每一个被 location 匹配的 <Route> 都将会被渲染。

<Route path='/home' component={Home}></Route>
<Route path='/home/user' component={About}></Route>
<Route  component={Main}></Route>

如上述代码,如果 url 是 home,那么 <Home> <About> <Main> 等组件都会被渲染,因为他们的 path 都被匹配到。

然而有时我们只想选择性的渲染一个 <Route> 。如果 Url 是 /home ,但我们并不想也匹配到 /home/user (或者显示给我们的 404 页面)。我们可以利用 Switch 来处理。

<Switch>
    <Route exact path='/home' component={Home}></Route>
    <Route path='/home/user' component={User}></Route>
    <Route path='/about' component={About}></Route>
    <Route  component={Main}></Route>
</Switch>

现在,如果 url 是 /home, <Switch> 将会开始寻找相匹配的 <Route><Route path="/home" /> 将会被匹配到,紧接着 <Switch> 会停止继续匹配并且渲染 <Home>。同理,如果URL是/home/user,那么将会被渲染。

exact 精确匹配的意思,如果 Route 中不添加 exact 那么就会进行模糊匹配,可能会匹配多个路由,渲染多个组件

参考文章:

posted @ 2020-12-07 22:09  公瑾当年  阅读(363)  评论(0编辑  收藏  举报