Skip to content

kodomozz/react-rotuer4

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

13 Commits
 
 
 
 
 
 
 
 

Repository files navigation

React-router Ver 4.3

在单页面应用最重要的就是路由,本文就简单的解读下react框架下最流行的路由模块react-router,由于react-rotuer每次版本更新变化较大,故本文只从react-router4.3 入手

概要:react-router是对history历史状态库的封装,使UI和URL进行同步,本文只是对具体实现的一个分析,的一些用法不再赘述

history

  • 老浏览器的history: 主要通过hash来实现,对应createHashHistory

  • 高版本浏览器: 通过html5里面的history,对应createBrowserHistory

  • node环境下: 主要存储在memeory里面,对应createMemoryHistory

上面针对不同的环境提供了三个API,但是三个API有一些共性的操作,将其抽象了一个公共的文件createHistory:

// 内部的抽象实现
function createHistory(options={}) {
  ...
  return {
    listenBefore, // 内部的hook机制,可以在location发生变化前执行某些行为,AOP的实现
    listen, // location发生改变时触发回调
    transitionTo, // 执行location的改变
    push, // 改变location
    replace,
    go,
    goBack,
    goForward,
    createKey, // 创建location的key,用于唯一标示该location,是随机生成的
    createPath,
    createHref,
    createLocation, // 创建location
  }
}

上述这些方式是history内部最基础的方法,createHashHistory、createBrowserHistory、createMemoryHistory只是覆盖其中的某些方法而已。其中需要注意的是,此时的location跟浏览器原生的location是不相同的,最大的区别就在于里面多了key字段,history内部通过key来进行location的操作。

function createLocation() {
  return {
    pathname, // url的基本路径
    search, // 查询字段
    hash, // url中的hash值
    state, // url对应的state字段
    action, // 分为 push、replace、pop三种
    key // 生成方法为: Math.random().toString(36).substr(2, length)
  }
}

path-to-regexp

在react-router4中用于将路径转化为正则, 再通过exec方法匹配路径 path-to-regexp

react-router 结构

+ -- react-router
+ -- react-router-config 
+ -- react-router-dom
+ -- react-router-native 
+ -- react-router-redux

一般使用只需引入react-router-dom即可,因为react-router-dom内部依赖了react-router 如果使用了redux则再引入 react-router-redux 如果是native应用,则再引入react-router-redux react-router-config是简化了路由的配置,拆分路由,统一引入,利于多人合作

基本原理

path-to-regexp

目录

附上一个简单路由实现,了解一下原理

Q&A

如果进入两个相同的路劲但是带的参数不一样(/:id)之类的,会重新加载页面吗?

 答案是会重新加载页面
 componentWillReceiveProps(nextProps, nextContext) {
   warning(
     !(nextProps.location && !this.props.location),
     '<Route> elements should not change from uncontrolled to controlled (or vice versa). You initially used no "location" prop and then provided one on a subsequent render.'
   );

   warning(
     !(!nextProps.location && this.props.location),
     '<Route> elements should not change from controlled to uncontrolled (or vice versa). You provided a "location" prop initially but omitted it on a subsequent render.'
   );

   this.setState({
     match: this.computeMatch(nextProps, nextContext.router)
   });
 }
 当地址栏发生变化时,route组件会进入`componentWillReceiveProps`生命周期方法

  return {
   path, // the path pattern used to match
   url: path === "/" && url === "" ? "/" : url, // the matched portion of the URL
   isExact, // whether or not we matched exactly
   params: keys.reduce((memo, key, index) => {
     memo[key.name] = values[index];
     return memo;
   }, {})
 };
  由于路劲参数不同 matchPath方法返回的match 对象的params参数发生了变化,且有一个setState方法,导致重新渲染
  注意点:这样的情况不会触发componentDidMount事件,react内部进行了dif操作,如果有子组件不同,则会替换子组件

About

react-rotuer4 源码浅析

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published