11.2.2 路由链接和嵌套
您可以在百度里搜索“深入浅出React和Redux 艾草文学(www.321553.xyz)”查找最新章节!
11.2.2 路由链接和嵌套
如果在这个单页应用中增加一个顶栏,包含所有页面的链接,这样只要所有网页都包含这个顶栏,那就可以方便地在不同页面之间切换了。
不过,我们不能直接使用HTML的链接,因为HTML的链接在用户点击的时候,默认行为是网页跳转,这样并不是一个“单页应用”应有的行为。
React-Router提供了一个名为Link的组件来支持路由链接,Link的作用是产生HTML的链接元素,但是对这个链接元素的点击操作并不引起网页跳转,而是被Link截获操作,把目标路径发送给Router路由器,这样Router就知道可以让哪个Route下的组件显示了。
顶栏作为一个功能组件,没有复杂功能,我们在src/TopMenu/index.js中直接定义它的视图,代码如下:
import React from 'react';
import {Link} from 'react-router';
const view = () => {
return (
Home
About
);
};
export {view};
Link组件的to属性指向一个路径,对应的路径在src/Routes.js中应该有定义,在这里两个Link分别指向了home和about,注意路径前面有一个“/”符号,代表从根路径开始匹配。
有了顶栏TopMenu组件之后,当然可以在Home、About和NotFound组件中引用这个TopMenu组件,但这是一个笨拙的做法,因为这要修改每一个页面文件。如果将来我们想要用另一个组件来替换TopMenu,又必须要修改每一个页面文件,非常不合适。
React-Router的Route提供了嵌套功能,可以很方便地解决上面的问题。
在src/pages/App.js中我们定义个新的React组件App,这个组件包含TopMenu组件,同时会渲染出Home、About或者NotFound页面,代码如下:
import React from 'react';
import {view as TopMenu} from '../components/TopMenu';
const App = ({children}) => {
return (
{children}
);
};
export default App;
上面的代码中看不见Home、About或者NotFound,因为它们都会作为App的子组件,children代表的就是App的子组件,所以App的工作其实就是给其他页面增加一个TopMenu组件。
在src/Routes.js中,我们导入App,利用一个Route组件将根路径映射到App组件上。
const Routes = () => (
);
现在,假如在浏览器中访问http://localhost:3000/home,那么React-Router在做路径匹配时,会根据路径“/home”的“/”前缀先找到component为App的Route,然后根据剩下来的“home”找到component为Home的Route,总共有两个Route,那应该渲染哪一个呢?
React-Router会渲染外层Route相关的组件,但是会把内层Route的组件作为children属性传递给外层组件。所以,以本例来说,在渲染App组件时,渲染children属性也就把Home组件渲染出来了,最终的效果是在TopMenu和Home组件都显示在页面上。
同样,因为包含About和NotFound的Route也居于包含App的Route之下,所以这两个页面上也可以看见TopMenu组件,如图11-3所示。
图11-3 包含TopMenu的Home页面效果
通过点击TopMenu组件上的链接,用户可以在不同页面之间切换,可以注意到页面之间的切换并没有带来网页刷新。
建立Route组件之间的父子关系,这种方式,就是路由的嵌套。
嵌套路由的一个好处就是每一层Route只决定到这一层的路径,而不是整个路径,所以非常灵活,例如,我们可以修改App的Route属性path如下:
上面的Route规则把关于App的Route规则改成路径为“/root”,那么,访问Home的路径就变成了http://localhost:3000/root/home,而关于Home、About和NotFound的Route却并不用做任何修改,因为每个Route都只匹配自己这一层的路径,当App已经匹配root部分之后,Home只需要匹配home部分。 深入浅出React和Redux