componentWillReceiveProps、static getDerivedStateFromProps與Dialog

需求

最近在作React Native項目中須要用到Picker選擇器,考慮到時間成本以及項目自己樣式的統一性,(實際上樣式問題已經遠遠排在了功能需求以後),因而本身設計了一個Picker組件。Picker功能就是:點擊顯示彈窗,彈窗中間顯示選擇列表,點擊列表項和取消按鈕關閉彈窗同時選中項傳遞到父組件html

組件設計

  1. props就簡單設計了visiable(顯示控制)style(樣式)、value(默認選中項)、data(數據源),因爲數據源是key:value形式,可是可能會有多種格式的key:value,就把key和value的字段也當成props傳進來myKey(自定義數據源key)、name(自定義數據源value)

Tip:有個小問題,key 不能做爲 props 傳遞,在組件中獲取不到。react

問題

其實無非就是一個彈窗的設計而已,可是問題也是出如今彈窗的關閉上。按照經驗,組件能夠由組件內部和組件外部關閉。 visiable 從props轉爲當前組件的state,而後操做本地的state就能實現功能。 剛開始是用getDerivedStateFromProps來作的,利用 nextProps.visiable!== prevState.visiable 返回 {visiable:nextProps.visiable}實現組件更新,問題來了,組件並無更新。分別打印getDerivedStateFromProps的兩個參數(nextProps, prevState)的時候,發現操做本地state後,getDerivedStateFromProps這個函數會執行,因爲props仍是以前的props就致使上一次的props覆蓋掉了剛修改的state。 而componentWillReceiveProps只有一個nextprops參數,操做本地state就能改變組件狀態了。可是既然官方更新了就使用最新的吧。 因而就多設計了一個props:hidden方法去更改父組件的 visiable來控制彈窗的顯示與否函數

反思

其實想一下應該是沒毛病的,react主張的就是單項數據流,保證組件數據源要單一,這樣才能保證組件受控,組件顯示與否要不就組件內部完成,要不就由組件外部控制,多個數據源好像確實不符合react的設計😄設計


--------------------------2019/05/28編輯--------------------------

官方關於這個問題的說明code

他們反覆強調的也是一個組件的數據來源要保持惟一性,徹底受控(徹底依靠props去更新組件),非受控(數據只保存在組件內部的 state )component

常見的錯誤就是把二者混爲一談。當一個派生 state 值也被 setState方法更新時,這個值就不是一個單一來源的值了。例如控制Dialog是否顯示的時候,咱們經過props能夠在組件外部控制Dialog是否顯示,可是若是咱們也想在組件內部改變這個狀態,對組件來講,這個數據是多來源的,致使的問題就是組件管理混亂。htm

  1. 受控組件: 咱們經過props能夠在組件外部控制。不要直接複製(mirror) props 的值到 state 中,而是去實現一個受控的組件,而後在父組件裏合併兩個值。好比,不要在子組件裏被動的接受 props.value 並跟蹤一個臨時的 state.value,而要在父組件裏管理 state.draftValue 和 state.committedValue,直接控制子組件裏的值。這樣數據才更加明確可預測。blog

  2. 不受控的組件,當你想在 prop 變化(一般是 ID )時重置 state 的話,能夠選擇一下幾種方式: 建議: 重置內部全部的初始 state,使用 key 屬性 選項一:僅更改某些字段,觀察特殊屬性的變化(好比 props.userID)。 選項二:使用 ref 調用實例方法。ip

因此,設計組件時,重要的是肯定組件是受控組件仍是非受控組件get

相關文章
相關標籤/搜索