最近需要開發一個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();