State
組件應該儘量是無狀態的,儘量使用 函數式組件而非類組件
時機
有時候,並不需要把所有的數據放到state中,render需要依賴的才需要放到state中

setState
setState是異步的,如果依賴原先的state或者props,那麼我們需要傳給它一個函數而非一個 plain object
官方例子

測試例子
此例子中,我希望點擊一次,執行兩次setState, foo從10變為12,但如果我兩次都使用plain object(見註釋) ,依賴 this.state.foo, 那麼 最終foo只會從10 變成11。 為什麼? 因為 第二次setState用到foo的時候, this.state.foo 取的值還是最先前的10。 所以一句話: 如果setState依賴當前state或者 props,那麼就要用函數,別用註釋中的那種用法。

state or computed function?
場景一:
get isCreating() {
return this.props.contractEditType === 'create'
}
場景二:
const {contract = {}} = props
const isFree = contract.paymentType === 'free'
const isSupplement = contract.category === 'supplement'
this.state = {
isFree,
isSupplement,
}
如果 接收props,但是呢 需要進行一些計算處理, 那麼我應該在constructor中進行處理, 處理之後放到state, 還是應該 寫個function 在render的時候 對props進行計算?
答案: 如果props老是變化,那麼就別放到state中, 因為constructor中需要處理一次, 還需要在componentWillReceiveProps中再次處理一次, 這時候採取場景一的方案比較好; 如果props在此組件初始化之後就恆定不變,那麼就放在state裡面,是沒問題的。
官方示例
doc.react-china.org/docs/liftin…
如果某些數據可以由props或者state提供,那麼它很有可能不應該在state中出現。舉個例子,我們僅僅保存最新的編輯過的
temperature
和scale
值,而不是同時保存celsiusValue
和fahrenheitValue
。另一個輸入框中的值總是可以在render()
函數中由這些保存的數據計算出來。這樣我們可以根據同一個用戶輸入精準計算出兩個需要使用的數據。// render函數中進行 convert計算 render() { const scale = this.state.scale; const temperature = this.state.temperature; const celsius = scale === 'f' ? tryConvert(temperature, toCelsius) : temperature; const fahrenheit = scale === 'c' ? tryConvert(temperature, toFahrenheit) : temperature;
事件
值得注意的是,通過
bind
方式向監聽函數傳參,在類組件中定義的監聽函數,事件對象e
要排在所傳遞參數的後面 doc.react-china.org/docs/handli…
最佳實踐: 使用屬性初始化器語法
如果要傳遞 參數 e
作為 React 事件對象, 那麼應該約定好, 都作為最後一個參數傳給回調函數比較好。
組合
doc.react-china.org/docs/compos…
屬性和組合為你提供了以清晰和安全的方式自定義組件的樣式和行為所需的所有靈活性。請記住,組件可以接受任意元素,包括基本數據類型、React 元素或函數。
主要用法 props.children
JSX
null,undefined,false, true 這幾個值會被jsx忽略, 即 不會渲染出來, 如果想要渲染,需要轉換為字符串{‘undefined’}
React 版本
16.0.0 (September 26, 2017) => 16.3.0 (March 29, 2018) => 16.4.1 (June 13, 2018)
生命週期 & 參數
componentWillMount
但此方法已經廢棄, 儘量使用 constructor和 componentDidMount , constructor中初始化state
在componentWillMount 中進行 setState, 不會導致多餘的render, render函數只會執行一次。
在在componentWillMount 中進行 dispatch action到redux, 會執行兩次render (即便是同步的action), 經我測試發現 mapStateToProps也會執行兩次 (dva中測試如下, cc的初始值為 90, dispatch之後變為了312) (前提是此組件有使用此prop)

componentDidMount
componentWillReceiveProps
在此時setState 不會引起 多餘的render, 是安全的。一般在此方法中可以進行對比props,然後選擇是否要setState
componentWillReceiveProps(nextProps){
}
shouldComponentUpdate
shouldComponentUpdate: function(nextProps, nextState){
return this.state.checked === nextState.checked;
//return false 則不更新組件
}
componentWillUpdate
即將渲染之前執行, 注意,別在此方法裡面進行 更新 props 或者 state
componentWillUpdate(nextProps,nextState)
componentDidUpdate
componentDidUpdate(prevProps,prevState)
生命週期圖示

參考鏈接
reactjs.org/blog/2018/0… => 不應該在componentWillMount 中 fetch 數據, 而應該在componentDidMount 中fetch.