react-router和react-router-dom的区别
RR4 本次采用单代码仓库模型架构(monorepo),这意味者这个仓库里面有若干相互独立的包,分别是:
react-router
React Router 核心react-router-dom
用于 DOM 绑定的 React Routerreact-router-native
用于 React Native 的 React Routerreact-router-redux
React Router 和 Redux 的集成react-router-config
静态路由配置的小助手
引用
react-router 还是 react-router-dom?
在 React 的使用中,我们一般要引入两个包,react
和 react-dom
,那么 react-router
和react-router-dom
是不是两个都要引用呢?
非也,坑就在这里。他们两个只要引用一个就行了,不同之处就是后者比前者多出了 <Link>
<BrowserRouter>
这样的 DOM 类组件。
因此我们只需引用 react-router-dom
这个包就行了。当然,如果搭配 redux ,你还需要使用 react-router-redux
。
react-router-v4
,我称之为“第四代react-router”,react-router
和react-router-dom
的区别是什么呢?
为什么有时候我们看到如下的写法:
写法1:
import {Swtich, Route, Router, HashHistory, Link} from 'react-router-dom';
写法2:
import {Switch, Route, Router} from 'react-router';
import {HashHistory, Link} from 'react-router-dom';
先简单说下各自的功能:
react-router
: 实现了路由的核心功能react-router-dom
: 基于react-router
,加入了在浏览器运行环境下的一些功能,例如:Link
组件,会渲染一个a
标签,Link组件源码a
标签行; BrowserRouter
和HashRouter
组件,前者使用pushState
和popState
事件构建路由,后者使用window.location.hash
和hashchange
事件构建路由。
react-router-native
: 基于react-router
,类似react-router-dom
,加入了react-native
运行环境下的一些功能。
从源码层面来说明:
首先看react-router-dom
中的Switch
组件的源码
// Written in this round about way for babel-transform-imports
import { Switch } from 'react-router'
export default Switch
只是从react-router
中导入Switch
组件,然后重新导出而已。
查看其他模块的源码,Route
组件的源码Router
组件的源码
...
和Swtich
一样,都是从react-router
中导入了相应的组件,重新导出而已,并没有对实现做什么特殊处理。
结论:
react-router-dom
依赖react-router
,所以我们使用npm
安装依赖的时候,只需要安装相应环境下的库即可,不用再显式安装react-router
。- 基于浏览器环境的开发,只需要安装
react-router-dom
;基于react-native
环境的开发,只需要安装react-router-native
。 npm
会自动解析react-router-dom
包中package.json
的依赖并安装。
react-router-dom
中package.json
依赖:
"dependencies": {
"history": "^4.7.2",
"invariant": "^2.2.2",
"loose-envify": "^1.3.1",
"prop-types": "^15.5.4",
"react-router": "^4.2.0",
"warning": "^3.0.0"
}
安装了react-router-dom
,npm
会解析并安装上述依赖包。可以看到,其中包括react-router
。
- 所以,回到最开始的写法。基于浏览器环境的开发,写法1就可以了。