共计 3819 个字符,预计需要花费 10 分钟才能阅读完成。
React Router v4 是对 React Router 的一次彻底重构,采用动态路由,遵循 React 中一切皆组件的思想,每一个 Route(路由) 都是一个普通的 React 组件。
BrowserRouter 创建的 URL 形式如下:http://react.com/some/pathHashRouter 创建的 URL 形式如下:http://react.com/#/some/path
使用 BrowserRouter 时,一般还需要对服务器进行配置,让服务器能正确处理所有可能的 URL. 例如,当浏览器发送 http://react.com/some/path 和 http://react.com/some/path2 两 …,服务器能够返回正确的 HTML 页面(也就是单页面应用中唯一的 html 页面 ). 使用 HashRouter 则不存在这个问题,因为 hash 部分的内容会被服务器自动忽略,真正有效的是 hash 前面的部分,而对于单页面应用来说,这部分内容是固定的。
路由的配置
1.path
(1) 当使用 BrowserRouter 时,path 用来描述这个 Route 匹配的 URL 的 pathname(2) 当使用 HashRouter 时,path 用来描述这个 Route 匹配的 URL 的 hash.
2.match
(1)params: Route 的 path 可以包含参数,例如:<Route path=’/foo/:id’> 包含一个参数 id。params 就是用于从匹配的 URL 中解析出 path 中的参数,例如:当 URL=”http://react.com/foo/ 1 时,params={id:1}。(2)isExact: 是一个布尔值,当 URL 完全匹配时,值为 true; 当 URL 部分匹配时,值为 false. 例如:当 path=”/foo”,URL=”http://react.com/foo” 时,是完全匹配;当 URL=”http://react.com/foo/ 1 时,是部分匹配。(3)path: Route 的 path 属性,构建嵌套路由时会使用到。(4)url: URL 的匹配部分。
3.Route 渲染组件的方式
(1)componentcomponent 的值是一个组件,当 URL 和 Route 匹配时,component 属性定义的组件就会被渲染。<Route path=’/foo’ component={FOO}> 当 URL=”http://react.com/foo” 时,Foo 组件会被渲染。(2)renderrender 的值是一个函数,这个函数返回一个 React 元素,这个函数返回一个 React 元素。这种方式可以很方便的为待渲染的组件传递额外的属性。例如:<Route path=’/foo’ render={(props)=>(
<Foo {…props} data={extraProps} />
)}>Foo 组件接收了一个额外的 data 属性。(3)children children 的值也是一个函数,函数返回要渲染的 React 元素。与之前两种方式不同的是,无论是否匹配成功,children 返回的组件都将会被渲染。但是当匹配不成功时,match 属性为 null。例如:<Route path=’/foo’ children={(props)=>(
<div className={props.match?’active’:”}>
<Foo />
</div>
)} /> 如果 Route 匹配当前 URL, 待渲染元素的根节点 div 的 class 将被设置成 active。
4.Switch 和 exact 当 URL 和多个 Route 匹配时,这些 Route 都会执行渲染操作。如果只想让第一个匹配的 Router 渲染,那么可以把这些 Route 包到一个 Switch 组件中。如果想让 URL 和 Route 完全匹配时,Route 才渲染,那么可以使用 Route 的 exact 属性。Switch 和 exact 常常联合使用,用于应用首页的导航。例如:<Router>
<Switch>
<Route exact path=’/’ component={Home} />
<Route path=’/posts’ component={Posts} />
<Route path=’/:user’ component={User} />
</Switch>
</Router> 如果不使用 Switch,当 URL 的 pathname 为 ”/posts” 时,<Route path=’/posts’/> 和 <Route path=’/:user’ /> 都会被匹配。如果不使用 exact,”/” “/posts” “/user1″ 等几乎所有 URL 都会匹配第一个 Route,又因为 Switch 的存在,后面的两个 Route 永远也不会被匹配。使用 exact, 保证只有当 URL 的 pathname 为 ”/” 时,第一个 Route 才会被匹配。
5. 嵌套路由
嵌套路由是指在 Route 渲染的组件内部定义新的 Route. 例如:const Posts = ({match}) => {
return(
<div>
{/* 这里 match.url 等于/posts*/}
<Route path={`${match.url}/:id`} component={PostDetail} />
<Route exact path={match.url} component={PostList} />
</div>
)
} 当 URL 的 pathname 为 ”/posts/react” 时,PostDetail 组件会被渲染;当 URL 的 pathname 为 ”/posts” 时,PostList 组件会被渲染。Route 的嵌套使用让应用可以更加灵活的使用路由。
6. 链接
Link 是 React Router 提供的链接组件,一个 Link 组件定义了当点击该 Link 时,页面应该如何路由:例如:const Navigation = () => (
<header>
<nav>
<ul>
<li><Link to=’/’>Home</Link></li>
<li><Link to=’/posts’>Posts</Link></li>
</ul>
</nav>
</header>
)Link 使用 to 属性声明要导航到 URL 地址。to 可以是 string 或 object 类型,当 to 为 object 类型时,可以包含 pathname、search、hash、state、四个属性,例如:<Link to={{
pathname:’/posts’,
search:’?sort=name’,
hash:’#the-hash”,
state:{formHome:true}
}}/> 除了使用 Link 外,我们还可以使用 history 对象手动实现导航,history 中最常用的方法是 push(path,[state]) 和 replace(path,[state]),push 会向浏览器历史记录中新增一条记录,replace 会用新纪录替换当前纪录,例如:
history.push(‘/posts’)history.replace(‘/posts’)
import React from “react”;import {BrowserRouter as Router, Route, Link} from “react-router-dom”;
function BasicExample() { return (
<Router>
<div>
<ul>
<li>
<Link to=”/”>Home</Link>
</li>
<li>
<Link to=”/about”>About</Link>
</li>
<li>
<Link to=”/topics”>Topics</Link>
</li>
</ul>
<hr />
<Route exact path=”/” component={Home} />
<Route path=”/about” component={About} />
<Route path=”/topics” component={Topics} />
</div>
</Router>
);}
function Home() { return (
<div>
<h2>Home</h2>
</div>
);}
function About() { return (
<div>
<h2>About</h2>
</div>
);}
function Topics({match}) {return (
<div>
<h2>Topics</h2>
<ul>
<li>
<Link to={`${match.url}/rendering`}>Rendering with React</Link>
</li>
<li>
<Link to={`${match.url}/components`}>Components</Link>
</li>
<li>
<Link to={`${match.url}/props-v-state`}>Props v. State</Link>
</li>
</ul>
<Route path={`${match.path}/:topicId`} component={Topic} />
<Route
exact
path={match.path}
render={() => <h3>Please select a topic.</h3>}
/>
</div>
);}
function Topic({match}) {return (
<div>
<h3>{match.params.topicId}</h3>
</div>
);}
export default BasicExample;