阅读 253

React生态渐进系列-React-Router

首先,确实很久没有写过文章了,感觉很多东西需要重新梳理一遍,所以首先从React项目的基础生态圈,开始慢慢的梳理这些前端项目的知识点.这次便详细的梳理一下路由的知识点.

单页应用(SPA)

提到前端的路由就必须提到单页应用,目前单页应用已经慢慢深入到所有的项目中,除了以前老旧的项目,新的项目基本上都开始使用单页应用.

什么是单页应用

单页Web应用(single page web application,SPA),就是只有一张Web页面的应用,是加载单个HTML 页面并在用户与应用程序交互时动态更新该页面的Web应用程序。

单页应用的特点

  • 速度:更好的用户体验,让用户在web app感受native app的速度和流畅,

  • MVVM:经典MVVM开发模式,前后端各负其责。

  • ajax:重前端,业务逻辑全部在本地操作,数据都需要通过AJAX同步、提交。

  • 路由:在URL中改变浏览器路由,页面并不会重载。

    单页Web应用(single page web application,SPA)是当今网站开发技术的弄潮儿,很多传统网站都在或者已经转型为单页Web应用,新的单页Web应用网站(包括移动平台上的)也如雨后春笋般涌现在人们的面前,如Gmail、Evernote、Trello等。如果你是一名Web开发人员,却还没开发过或者甚至是没有听说过单页应用,那你已经Out很久了。 单页Web应用和前端工程师们息息相关,因为主要的变革发生在浏览器端,用到的技术其实还是HTML+CSS+JavaScript,所有的浏览器都原生支持,当然有的浏览器因为具备一些高级特性,从而使得单页Web应用的用户体验更上一层楼。关于单页应用的优点和缺点,网上讲解的文章有很多,这里就不展开论述了。 单页Web应用,顾名思义,就是只有一张Web页面的应用。浏览器一开始会加载必需的HTML、CSS和JavaScript,之后所有的操作都在这张页面上完成,这一切都由JavaScript来控制。因此,单页Web应用会包含大量的JavaScript代码,复杂度可想而知,模块化开发和设计的重要性不言而喻。

首先帮大家回顾一下单页应用相关的知识,其中,路由在单页应用扮演者非常重要的角色.

React-Router

接下来,就慢慢了解,React-Router是如何在项目中扮演路由控制器这一角色的.用法的话,可以去React-Router官网查看详细的用法,在这里,讲解的是具体实现.

React-Router是React官方推荐的路由组件.在经历过3 => 4版本的颠覆性重构之后,变得非常的轻量简介,和React的搭配更加的天衣无缝. React-Router目前分为React-Router和React-Router-Dom两个库,其意义和React以及React-Dom有着异曲同工之妙,React-Router是一种路由渲染的思想,React-Router便将路由渲染和DOM结合起来,来渲染我们的单页应用,所以我们直接来看一下React-Router-DOM的实现.

一共就只有这些组件,接下来我们来结合用法一个一个分析:

BrowserRouter,HashRouter

import { BrowserRouter } from 'react-router-dom'
ReactDOM.render((
  <BrowserRouter>
    <App/>
  </BrowserRouter>
), contianer)
复制代码

这两个组件为我们提供了全局组件的history方法,当我们用这两个组件,之后就可以使用路由对象history. 可以看一下history对象的具体实现:

import { createBrowserHistory as createHistory } from "history";

class BrowserRouter extends React.Component {
  ...
  history = createHistory(this.props);
  ...
  render() {
    return <Router history={this.history} children={this.props.children} />;
  }
}
复制代码

history是由一个名字叫做history的包创建而来,而BrowserRouter和HashRouter的区别是,创建的是hash还是浏览器路径. 具体history不做分析,简单介绍一下browserHistory和HashRouter的区别.

这两个都是路由,不过BrowserHistory是借助浏览器的API.pushState和replaceState来操作路由,路由形式和正常的路由无异,hashRouter 是通过改变路由的hash值并且监听hash变化,来改变路由.

Router

Router组件是React-Router的核心,他负责提供context来传达全局的router属性.

getChildContext() {
    return {
      router: {
        ...this.context.router,
        history: this.props.history,
        route: {
          location: this.props.history.location,
          match: this.state.match
        }
      }
    };
  }

复制代码

Route

Route组件是用的最多的组件,他表示一个路由组件,匹配渲染. 使用方法

<Router>
  <div>
    <Route exact path="/" component={Home}/>
    <Route path="/news" component={NewsFeed}/>
  </div>
</Router>
复制代码

当符合其中的路由匹配规则,component组件便会被渲染出来,匹配机制在Route内部实现.

computeMatch(
    { computedMatch, location, path, strict, exact, sensitive },
    router
  ) {
    if (computedMatch) return computedMatch; // <Switch> already computed the match for us

    invariant(
      router,
      "You should not use <Route> or withRouter() outside a <Router>"
    );

    const { route } = router;
    const pathname = (location || route.location).pathname;

    return matchPath(pathname, { path, strict, exact, sensitive }, route.match);
    }
复制代码

该方法会解析匹配规则,返回匹配值.

Switch

该组件会渲染第一个匹配的路由子组件, 核心代码如下:

let match, child;
React.Children.forEach(children, element => {
  if (match == null && React.isValidElement(element)) {
    const {
      path: pathProp,
      exact,
      strict,
      sensitive,
      from
    } = element.props;
    const path = pathProp || from;

    child = element;
    match = matchPath(
      location.pathname,
      { path, exact, strict, sensitive },
      route.match
    );
  }
});
复制代码

上面便是React-Router在浏览器环境整个的工作过程.

关注下面的标签,发现更多相似文章
评论