最近需要开发一个webApp,在 vue 和 react 之间犹豫很久,考虑到项目的小程序应用是基于 Taro 开发的,但是由于前期开发没有考虑转 H5 的需求,导致现在项目过于庞大,转 H5 需要大量的时间和精力处理兼容性问题。考虑到语法上的相似型(方便复制粘贴代码),所以还是选择搭建 一个 React 项目。因为第一次搭建,还是遇到了一些问题,做一些简单的记录方便以后不要再踩坑~~
第一步:创建项目
方法一:
首先我们需要全局安装 create-react-app
npm install -g create-react-app
然后直接执行
create-react-app my-app cd my-app npm start
方法二:
直接使用 npx 创建项目,你需要保证你的电脑上 Node >= 8.10 和 npm >= 5.6,在这个前提下
npx create-react-app my-app cd my-app npm start
这也是官方推荐的创建项目的方法。
第二步:配置 router
在一个有业务需求的react 项目中,路由是必不可少的,react 的脚手架没有帮我们安装路由,所以需要我们手动安装
npm install react-router-dom -S
我个人比较习惯单独用一个来管理路由,因此我创建了一个 router.js
文件,下面简单介绍一下在项目的搭建过程中涉及到的 React Router 的一些必备的知识点。
Histories
React router 常用的 history 有三种形式:browserHistory、hashHistory、createMemoryHistory,
1、browserHistory 是使用 React Router 的应用推荐的 history,它创建一个像 example.com/some/path 这样真实的 URL,使用这种模式,需要服务器做好相关配置,做好处理 URL 的准备。 2、hashHistory 使用 URL 中的 hash(#)部分去创建形如 example.com/#/some/path 的路由。 3、createMemoryHistory 不会在地址栏被操作或读取,适合服务端渲染的应用,使用这种方式需要先创建它
const history = createMemoryHistory(location)
注意 除了第三种形式外,react-router官方文档上说明的引用另外两种形式的方法都是:
import { browserHistory } from 'react-router' render( <Router history={browserHistory} routes={routes} />, document.getElementById('app') )
但是在实际的项目操作中,你会发现直接按照文档中的做法,运行时会报错:
Attempted import error: 'browserHistory' is not exported from 'react-router'.
查阅资料时发现,其实 React 项目中,一般不会安装 react-router
包,而是安装我上面安装的 react-router-dom
包,具体两者之间的区别可以参考这篇文章: react-router与react-router-dom使用时的区别
最终引用方法如下
import React from 'react'; import { BrowserRouter as Router} from 'react-router' export default function RouteConf() { return ( <Router> </Router> ) }
Switch
Switch 是唯一的,它仅渲染一个路径,如果不使用 Switch 包裹, 每一个被location匹配到的将都会被渲染。为了减少不必要的渲染,我们一般都会将路由用 Switch 组件包裹起来。
import React from 'react'; import { BrowserRouter as Router, Route, Switch } from 'react-router' export default function RouteConf() { return ( <Router> <Switch> <Route path="/" component={index} /> </Switch> </Router> ) }
关于 Switch 的详细介绍,可以参考这篇文章--> react-router v4 之 啥是 - 简书
exact
exact 是 Route 的一条属性,一般而言,react 路由会匹配所有匹配到的路由组件,使用 exact 属性可以严格匹配路由组件。
<Route path='/' component={Index} /> <Route path='/about' component={About}>
上面这两个路由,在未配置 exact 的路由中,如果匹配到的路由是 /about
,那么 /
也会被匹配出来。
<Route exact path='/' component={Index} /> <Route path='/about' component={About}>
使用 exact 配置后,就可以解决这个问题了。
代码分割
接下来介绍一下 React 的代码分割,在 React 应用中引入代码分割的最佳方式是通过动态 import() 语法,当 Webpack 解析到该语法时,会自动进行代码分割。
另外,React.lazy 函数能让你像渲染常规组件一样处理动态引入的组件。然后应在 Suspense 组件中渲染 lazy 组件,如此使得我们可以使用在等待加载 lazy 组件时做优雅降级(如 loading 指示器等)。
代码如下:
import React, { Suspense, lazy } from 'react'; import { BrowserRouter as Router, Route, Switch } from 'react-router-dom' const Index = lazy(() => import('./Index')); export default function RouteConf() { return ( <Router> <Suspense fallback={<div> Loading... </div>}> <Switch> <Route path="/" component={Index} /> </Switch> </Suspense> </Router> ) }
第三步:引用路由
我们要在 index.js 中引用刚刚配置好的 router.js 文件。
import React from 'react'; import ReactDOM from 'react-dom'; import Route from './router'; import * as serviceWorker from './serviceWorker'; const render = (Component) => { ReactDOM.render( <Component />, document.getElementById('root'), ) } render(Route); serviceWorker.register();
第四步:添加 fastClick
fastclick 是用来解决移动端的点击事件存在 300ms 延迟的问题的,我们在 index.js 中引用它
安装
npm install -S fastClick
引用
import React from 'react'; import ReactDOM from 'react-dom'; import fastClick from 'fastclick'; import Route from './router'; import './index.css'; import * as serviceWorker from './serviceWorker'; fastClick.attach(document.body); const render = (Component) => { ReactDOM.render( <Component />, document.getElementById('root'), ) } render(Route); serviceWorker.register();