在讲解 react-hot-loader 之前,我们先把 react 大致的框架搭建好。包括 react-router、redux、react-redux、redux-saga 等。
本篇主要介绍 react-router-v4 搭建。
项目结构调整
如图,目前所有新增目录并没有内容,仅调整了入口文件 index.js
路径,以及删除了用处不大的 main.js
。
*调整后,请修改 webpack.config.js
的入口文件(entry
)路径,以及修改 CSS 的导入路径等,否则会编译失败。
react-router 搭建
首先,我们的项目是单页 Web 应用(simple-page web application,SPA
),它跟我们传统的一个页面对应一个 HTML 不太一样。
单页应用的路由跳转:
- 浏览器的 url 发生改变,但其实并没有发送请求,也没有刷新整个页面。
- 根据我们配置的路由信息,每次切换路由,会根据配置来加载不同的组件,同时 url 地址也会发送变化。
- 主要有
HashRouter
和BrowserRouter
两种模式。 - 原理其实就是使用 HTML5 history API 来使你的内容随着 url 动态改变。
主要路线是:
index.html → index.js → App.js → router 配置 → 加载所匹配的组件 xxxComponent.js
我们的模板 HTML 里面有个 <div id="app"></div>
标签作为容器,接着我们在入口文件 index.js
通过 react-dom
的 render
函数将我们的 App.js
组件插入到其中。而 App.js
就是我们路由的根组件,然后我们的路由,又根据配置加载对应的 xxxComponent.js
子组件。
1. 安装 react-router-dom
react-router-dom
基于 react-router
,加入了在浏览器运行环境下的一些功能。我们无需再安装 react-router
了,因为在 yarn add react-router-dom
时,它就会帮我们安装了。
$ yarn add react-router-dom@5.2.0
2. 创建 App、Home、About、404 组件
App 组件
// App.js
import React, { Component } from 'react'
import { BrowserRouter, HashRouter as Router, Route, Switch, Link } from 'react-router-dom'
import { Home, About, NotFound } from './index'
class App extends Component {
render() {
return (
<Router>
<Switch>
<Route path="/" exact component={Home} />
<Route path="/about" exact component={About} />
<Route component={NotFound} />
</Switch>
</Router>
)
}
}
export default App
Home 组件
// pages/home/index.js
import React, { Component } from 'react'
class Home extends Component {
constructor(props) {
super(props)
this.state = {}
}
render() {
return <div>Home Component!</div>
}
}
export default Home
About 组件
// pages/about/index.js
import React, { Component } from 'react'
class About extends Component {
constructor(props) {
super(props)
this.state = {}
}
render() {
return <div>About Component!</div>
}
}
export default About
404 组件
// pages/404.js
import React, { Component } from 'react'
import { Link } from 'react-router-dom'
class NotFound extends Component {
constructor(props) {
super(props)
this.state = {}
}
render() {
return <div>Page not found! <br /> <Link to="/">Go back</Link></div>
}
}
export default NotFound
// pages/index.js
export { default as Home } from './home'
export { default as About } from './about'
export { default as NotFound } from './404'
3. 修改 src/index.js,以及新增 src/Root.js
// Root.js
import React from 'react'
import App from './pages/App'
const Root = () => {
return <App />
}
export default Root
// index.js
import React from 'react'
import { render } from 'react-dom'
import '../styles/style.css'
import Root from './Root'
// 最简单的 React 示例
const rootElem = document.getElementById('app')
render(<Root />, rootElem)
这里设计多一层 Root
是为了后面引入 Redux 抽离代码,看起来更加简洁一些。
最终目录结构如下:
至此,效果出来了
好了,我们的 react-router 基本搭建好了。
切换路由,http://localhost:8080/#/about 就能看到页面加载了 About Component!
。
关于 react-router 相关的补充说明
- react-router 相关 API 导入问题:
// 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'
// ************************************************************************
// Why?
// 我们从源码里面可以看到类似以下的这一段代码(截取),
// 比如 Switch,它实际上就是引用了 react-router 的 Switch.
// 所以我们直接用“写法一”即可
Object.defineProperty(exports, 'Switch', {
enumerable: true,
get: function () {
return reactRouter.Switch;
}
});
exports.BrowserRouter = BrowserRouter;
exports.HashRouter = HashRouter;
exports.Link = Link;
exports.NavLink = NavLink;
网友评论