React使用總結

兩種架構

如今使用React的開發模式主要有兩種——freeMarker+React以及純靜態React頁面開發。本文着重介紹純靜態React頁面的開發方式。html

freeMarker+React

因爲之前是用YUI+freeMarker進行開發,爲了保證之前的頁面都可以正常訪問,當重構老頁面時會使用這種開發方式。
在這種開發模式下由java利用freeMarker生成並Render爲html,經過browserify將js打包至資源目錄並在browser中加載,React將app render至div中。java

React純靜態頁面

利用browserify使用同構的方式進行開發,直接產出html以及js文件放置到資源文件中經過文件路徑訪問頁面。採用這種方式開發有如下優勢:node

  • PreRender產出的靜態資源文件加載速度快
  • 先後端只經過ajax進行交互,使得先後端分離,各自約定好接口以後就能進行開發。
  • 同構的開發模式使得功能模塊能夠複用,好比模板、node的一些經常使用模塊等等。

須要注意代碼能同時在browser與node環境下執行,不然會出問題。當使用bom對象時,在componentDidMount生命週期中運行,此時node環境下已經完成了first render。react

構建方式

在node環境下經過React.renderToString方法生成html,經過這種方式生成的標籤會帶有data-reactid屬性,儲存server render結果的校驗值。
當在browser中React.render時會檢查校驗值是否一致,保證node以及browser環境下render的結果一致。所以開發過程當中必定要保證render的結果保持一致,若是須要在browser中插入dom節點,可使用insert等操做。禁止state以及props在兩個環境下值不一樣。
若是經過校驗,則React不會從新生成dom,只將事件監聽器掛載在對應的節點下。ajax

應用架構

採用flux的思想來組織應用,具體的方案我推薦facebook的flux或者reflux,這也是如今Github中獲星最多的flux實現方案。二者的主要區別是reflux不經過Dispatcher來控制action的分發,reflux中使用了較多的magic來使得代碼更加簡潔高效。後端

若是項目的複雜程度不高(沒有多個互相關聯的store),我推薦使用Reflux,通常狀況下其實一個store就夠了,並且避免了處理store之間的通訊問題。數據結構

╔═════════╗       ╔════════╗       ╔═════════════════╗
║ Actions ║──────>║ Stores ║──────>║ View Components ║
╚═════════╝       ╚════════╝       ╚═════════════════╝
     ^                                      │
     └──────────────────────────────────────┘

若項目較爲龐大,考慮到代碼的可控性、直觀,以及更好地去控制各store之間的響應邏輯,使用flux更合適。架構

優勢

採用flux來構建應用有如下優點:app

  1. 將state在store中統一進行管理,實現業務與組建的分離,代碼結構更加清晰。
  2. 因爲action在store中進行監聽,所以事件不須要再一層層經過props來進行傳遞,簡化代碼,並且也更容易將應用拆分紅更細粒度的模塊。
  3. 儘可能使用props的狀況下,代碼可預測性很強。

組件開發

  1. react認爲組件就是一個狀態集,儘量使得組件只擁有props。
  2. 當組件須要有本身的處理邏輯時須要用到state,好比控制input的value,彈出層自動隱藏、顯示的邏輯等等。
  3. state並不會隨着porps的更新而改變,所以在使用 state 時必定要注意是否有 componentWillReceiveProps。
  4. 業務代碼爲了方便以及速度能夠不寫 PropTypes,可是可複用的組件使用 PropTypes 來保證組件的正常運行是必要的,組件中的工具方法能夠抽取出來寫測試用例。

setState

state爲key-value的集合,通常來講value都是基本類型,當state的數據結構層次很深的時候,操做state就會變成很頭疼的事情。前後端分離

深拷貝

// shallow copy
var state = deepCopy(this.state);
state.valueWantChange = vale;
this.setState(state);

深拷貝方法沒有問題,但因爲deepCopy效率很低,通常都不推薦使用。

forceUpdate

this.state.valueWantChange = vale;
this.forceUpdate(); // this.setState(this.state);

在如下兩種狀況會用到 forceUpdate

  • 手動更改了 state 以後須要觸發 render
  • 作了除更改props和state以外的操做後,須要render。

可是使用forceUpdate 會跳過 shouldComponentUpdate 的過程,會觸發子組件的全部lifeCycle方法(包括shouldComponentUpdate)從而形成性能的浪費。所以爲了組件更加清晰高效,應該避免使用forceUpdate。

Immutability Helpers

我推薦使用React.addons來管理state
You can alleviate this by only copying objects that need to be changed and by reusing the objects that haven't changed.

import react from 'react/addons'
var newData = React.addons.update(myData, {
  x: {y: {z: {$set: 7}}},
  a: {b: {$push: [9]}}
});
this.setState(newData);

下面是update的基本語法。若是用過mongo應該對此十分熟悉。

  • {$push: array} push() all the items in array on the target.
  • {$unshift: array} unshift() all the items in array on the target.
  • {$splice: array of arrays} for each item in arrays call splice() on the target with the parameters provided by the item.
  • {$set: any} replace the target entirely.
  • {$merge: object} merge the keys of object with the target.
  • {$apply: function} passes in the current value to the function and updates it with the new returned value.
相關文章
相關標籤/搜索