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.