react 經常使用生命週期

gitbub github.com/15997111963…javascript

如下UNSAFE_開頭的週期都是官方將要廢棄的週期html

保留UNSAFE_前綴還能夠繼續使用 在最新的16.9中將拋出warning 在17.0的大版本中完全移除componentWillMount、componentWillUpdate、componentWillReceiveProps這三個生命週期 幫助理解 但不建議繼續使用和學習java

組件掛載時

constructor()react

  • class的構造器 繼承父類Component能夠作一些基本的綁定操做
  • 能夠綁定ref(這裏指React.createdRef()這種建立方式)、給事件綁定this或是state根據props獲取的默認數據等
  • 只會觸發一次!!

static getDerivedStateFromProps(props, state)git

  • 新出的靜態週期 爲了替代 componentWillReceiveProps
  • 只有在父組件從新渲染 props發生變化纔會觸發
  • this.setState()不會觸發getDerivedStateFromProps
  • 若是想要觸發 須要this.forceUpdate(callback)=> {小常識:有時一些變量咱們無需在視圖層上展現 就會偷懶直接存到組件內部的this上 當咱們某些條件下修改這個值的時候並不會觸發從新渲染 這個時候咱們就能夠this.forceUpdate()手動觸發告訴react我要渲染 給我渲染!! 也請記住 這樣作會直接跳過本組件的shouldComponentUpdate()直接進行渲染 因此請儘可能避免這麼幹}
  • 在此週期內部沒法訪問到this 不少剛看到這個週期的人可能都不太理解 咱們在componentWillReceiveProps裏能夠根據當前props和下一次props的變動去進行this.setState或是派生數據之類的作法 可在這個週期裏 咱們沒法進行比較 那咱們該怎麼辦

在我我的看來這個週期是主要爲了能更好的派生數據 不少時候咱們當前須要用到的數據來自於props 而咱們也沒法直接使用props須要進行二次派生 這個時候咱們就能夠用這個週期將派生的數據存在state裏以供使用 而不是頻繁的觸發componentWillReceiveProps不停的render()github

static getDerivedStateFromProps(props, state) {
    if (state.data.length === 0 && props.data.length) {
        return { data: props.data }
    }
    return null
}
複製代碼

此方法的用法很好理解 是否須要更新state 不須要就return null 若是須要 能夠根據props和上一次的state作一些簡單的比較 return的對象就會更新state算法

若是咱們只想要更新state裏的data 但不更新其餘的 咱們不須要像redux裏同樣return {...state, data} 咱們只須要更新本身想要更新的那一條就能夠了redux

對於上面講到的不少時候須要根據當前props和下一次進行比較而作一些業務或是更新 這個時候咱們就能夠考慮使用componentDidUpdate 甚至是 shouldComponentUpdate(固然 考慮到週期的取名和合理性 咱們仍是儘可能避免這種姿式)api

UNSAFE_componentWillMount()瀏覽器

  • 此週期在render前觸發 有的人喜歡在這裏作一些訂閱或是監聽的操做 建議移到constructor或是componentDidMount

render()

  • 更新組件的propsstate返回一個React元素/節點
  • render是一個純函數 沒有反作用 也不該該有反作用 因此咱們不要在render裏作this.setState相似這種操做
  • 不負責最後的渲染工做
  • nullboolean不會被渲染

componentDidMount()

  • 組件掛載後 官方的話說就是已經插入dom節點 咱們須要作一些綁定的操做能夠在這裏
  • 方便作一些訂閱或是監聽在這裏
  • 綁定的ref在這是拿不到的
  • 咱們也能夠在這裏作一些修改state的操做 那將會觸發再次render(並不是瀏覽器頁面的再次渲染) 但儘可能避免這麼幹 至於爲何 這還用說嗎
  • constructor同樣 只會觸發一次

update更新時

既然是更新時 那就表明 下面這些會按順序所有都觸發!

固然 不徹底是這樣 組件內部state的更新不會觸發UNSAFE_componentWillReceivePropsgetDerivedStateFromProps

但若是是組件內部的state更新了 子組件用到了這裏的state(也就是子組件的props 父組件的state) 則會遵循規則 子組件會觸發這些週期 組件之間都會遵循這些機制

UNSAFE_componentWillReceiveProps(nextProps, nextState)

UNSAFE_componentWillReceiveProps(nextProps, nextState) {
        if (this.state.visible !== nextProps.visible) {
            this.setState({ visible: nextProps.visible })
        }
    }
複製代碼
  • 接收兩個參數 分別是下一次的props和下一次的state 咱們能夠在裏面比較兩次的變化而後to do something
  • 但也由於如此 很容易出現一些咱們沒法預估的bug出現
  • 以前這裏的週期名寫錯了 也沒人提醒一下我 很是抱歉~

static getDerivedStateFromProps(props, state)

  • 同上述同樣
  • 注意組件內部的state直接變化不會觸發這裏 如有須要 能夠this.forceUpdate(callback) 同上
  • 若是是props的數據變化觸發此週期 再次派生state 這裏的觸發是由於props 而不是單純的組件內部state變化

shouldComponentUpdate(nextProps, nextState)

官方認爲state每次更新了 就應該從新render 大部分狀況下咱們應該遵循渲染的規則

大多出如今須要優化的地方propsstate不可控 頻繁觸發render的時候 如長時間的倒計時等

只做爲優化而存在 也可參考使用PureComponent淺比較組件

若你使用的是純函數式組件也想達到此效果或是目的可使用React.memo()

若是你也在同時學習或使用hook 你也可使用useMemo

shouldComponentUpdate(nextProps, nextState){
        if (this.props.value !== nextProps.value) {
            return true
        }
        return false
    }
複製代碼
  • 接收兩個參數 下一次拿到的props和下一次拿到的state
  • 這個週期是render渲染前的最後一個週期 表明是否render(除開componentWillUpdate將要廢棄)。
  • 在最後必定要返回一個false表明不渲染 不然會出現意想不到的影響。
  • return false前能夠根據當前的this.props || this.state等等裏面的某些值進行判斷 須要渲染就 return true
  • 若是判斷是否渲染的條件裏要用到循環或是JSON.parse JSON.stringify等序列化 反序列化的操做 性能可能更差 不如不用

UNSAFE_componentWillUpdate(nextProps, nextState)

  • 在更新發生前被當即調用 你不能在此調用this.setState()dispatch等操做觸發組件再次更新
  • 在這個時候作任何操做其實都是不合理的 不管是致使props仍是state的改變再次致使重複性的工做 反作用不可想象
  • 確實有須要 請移步componentDidUpdate
  • 官方將其廢除這個作法很是的nice!!

getSnapshotBeforeUpdate(prevProps, prevState)

  • 這個方法會在把渲染結果提交到DOM以前被調用 它能夠返回一個參數
  • 這個參數被componentDidUpdate(prevProps, prevState, snapshot)方法的第三個參數接收
  • 官方的說法是組件能在發生更改以前從DOM中捕獲一些信息(例如滾動位置)
  • 我是尚未遇到過使用場景太細節也不清楚

render()

  • 各類將數據過濾轉譯成字符串 diff算法 更新部分更改部分等等操做 而後生成節點 同上

componentDidUpdate(prevProps, prevState, snapshot)

componentDidUpdate(prevProps, prevState, snapshot) {
        if (this.props.value !== prevProps.value) {
          this.changeValue(this.props.value)
        }
    }
複製代碼
  • 在更新發生後被當即調用。能夠在DOM更新完以後作一些收尾的工做 也就是說 首次掛載必定不會觸發 別理解錯
  • 咱們能夠在這裏作一些原來使用UNSAFE_componentWillUpdate所作的一些根據上一次props state和下一次的不一樣而觸發的邏輯或是業務須要
  • 但和UNSAFE_componentWillUpdate不一樣 這裏接收到的是上一次的propsstate

卸載時

componentWillUnmount()

  • 咱們能夠在這邊作收尾工做 清除計時器、訂閱、監聽等等
  • 大多數時候會出現一些this.setState不能對不存在的組件進行修改的警告甚至是報錯
  • 其實就是組件已經卸載(銷燬)了 異步的this.setState還在修改已銷燬的state 固然拿不到
  • 因此有時咱們須要如下種種姿式
componentWillUnmount() {
    this.setState = (state, callback) => { return }
    window.removeEventListener()
    clearInterval()
}
複製代碼

這是本人曾經學習到使用後來一點點積累的筆記整理出來的 僅供參考 若是有寫的不對的有是遺漏 歡迎及時指出

已同步到簡書

相關文章
相關標籤/搜索