React-Router

Posted 瓶子2333

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了React-Router相关的知识,希望对你有一定的参考价值。

我仍然记得实习的时候,公司的PC官网首页是一个典型的上中下结构。在首部点击导航的某个链接时,跳转到另一个页面,但是首部和底部是一样的。也就是说,虽然服务器返回了一个完整的html,但不同的只是中间部分的内容。

SPA是现在最流行的多页面应用方案,当我们点击页面的链接时,视觉上像是到了另一个页面,实际上页面还是原来的页面,只是局部内容被替换掉了,而且url也用history的api重写而已。

单页面应用要达到两个目标:

1.不同页面的切换不会造成刷新。

2.页面内容和url一致。

注意第二点有两种情况,一是页面上点击链接时,内容替换,url也跟着改变;二是在地址栏输入url时,页面会显示对应的内容而不是默认页面内容。这就要求服务器能够正确回应url请求。

这几天学习react一直用的是create-react-app这工具,create-react-app创建的应用具备上述要求的服务器功能,即配置后备(fallback)URL。所以我们可以先不关注这个。

React-Router:

学习过vue-router的朋友在接触React-Router的时候会发现,vue-router和它在设计非常相似。

首先我们要认识到,每个url都有域名和路径两部分。因为 app可以部署在任何域名下,所以url显示什么内容取决于路径部分,和域名端口无关。而我们在路由跳转时,要替换的“页面”实际上是DOM结构(从vue或react的角度,是组件)。在开发SPA是时,“页面”就是组件。

React-Router提供了两个组件:Router和Route。下面看最简单的例子:

src/Routes.js

 1 import React from ‘react‘
 2 import {Router,Route,browserHistory} from ‘react-router‘
 3 
 4 import Home from ‘./pages/Home.js‘
 5 import About from ‘./pages/About.js‘
 6 import NotFound from ‘./pages/NotFound.js‘
 7 
 8 const history = browserHistory;
 9 const Routes = () =>(
10   <Router history = {browserHistory}>
11     <Route path = "home" component = {home}>
12     <Route path = "about" component = {About}>
13     <Route path = "*" component = {NotFound}>
14   </Router >
15 );
16 export default Routes;

Routes.js文件返回一个组件,该组件输出一个Router组件实例,路由及其规则都封装在里面,Route组件内的path和component把路径和组件对应起来。

路由链接:

  HTML的链接被点击时会发生默认跳转,这不符合单页面应用的要求,所以React-Router提供了一个<Link>组件来支持路由链接。

  1.<link>组件产生html链接。

  2.对该链接的点击不会引发跳转,而是把目标路径发送给Router,让Router依据关联显示对应的组件。

  3.<Link>组件的to指向一个路径,对应的路径在Router中应该有定义。

 1 import React from ‘react‘
 2 import {Link} from ‘react-router‘
 3 
 4 const view = ()=>{
 5   <div>
 6     <ul>
 7       <li><Link to="/home">Home</Link></li>
 8       <li><Link to="/about">About</Link></li>
 9     </ul>  
10   </div>
11 };

嵌套:

Route提供了嵌套功能。路由的嵌套和组件层级的显示是对应的。当我们触发了子路由的跳转时,父层路由显示的东西可以依然保留在页面上,只有子层路由对应的组件发生变更。

比如在src/pages/App.js中定义组件App:

 1 import React from ‘react‘
 2 import {view as TopMenu} from ‘../components/TopMenu‘
 3 
 4 const App = ({children}) =>{
 5   return (
 6     <div>
 7       <TopMenu />
 8       <div>{children}</div>
 9     </div>
10   )
11 }
12 export default App

上面代码中children是App的子组件。这是React中原生的特性。

React-Router中路由嵌套需要组件和Route的双边设置:

  在组件中将children获得的子组件在恰当位置渲染;

  在Route中 ,则是设置嵌套的<Route>

1 const Routes = ()=>(
2   <Router history = {browserHistory}>
3     <Route path = "/" component = {App}>
4       <Route path = "hone" component={home} />
5       <Route path = "hone" component={home} />
6       <Route path = "hone" component={home} />
7     </Route>
8   </Route>
9 );

当我们访问 /home时,React-Router在做路由匹配时,会先找到“/”对应的Route,再找到“home”对应的Route。它会先渲染外层Route对应的组件,然后把内层组件作为chidren传给外层组件。

这也是为什么我们外层组件要特地将{chidlren}写在return的JSX中。

嵌套路由的一个好处是,每个路由Route只匹配自己这一层的路径,不影响其他层的路由。当我们修改“/”成“/root”的时候,子层的home、about不会受影响,将变成“/root/home”。

默认链接:

  插件提供了<IndexRoute>作为某个目录下的默认路由。比如我们在地址栏如果只输入“/”,app将只显示App这个组件所代表的导航,但并不显示其他内容。我们可以在它子层添加<IndexRoute component={Home} /> 让它默认显示Home组件(作为chidlren)。

 

以上是关于React-Router的主要内容,如果未能解决你的问题,请参考以下文章

React-Router学习

使用 webpack 和 react-router 进行延迟加载和代码拆分不加载

如何使此代码与 react-router v6 兼容

react-router 学习笔记

react-router 4实现代码分割(code spliting)

React-Router如何防止重定向