react16.8 新的生命周期getDerivedStateFromProps和 getSnapshotBeforeUpdate 用法


前言:React 16.8 更新了一些新的生命周期,增加了hooks無狀態組件,原有的class類組件的生命周期也進行了更新優化

我認為hooks才是React想做的事,React不想廢棄原來的類組件,同時想扶正hooks,做了一些兼容,寫法上的區別,但是最終結果是一樣的,

下面我們來討論一下新增加的生命周期:

1、getDerivedStateFromProps(props,state)

  • 相當於componentwillmount 和 componentWillReceiveProps合並
  • 主要是應用在於封裝組件時調用,組件的state取決於props變化,
  • 無條件的根據 props來更新內部 state,也就是只要有傳入 props值, 就更新 state
  • 只有 props 值和 state值不同時才更新 state 值。

我們自己查看會發現這不就是和React.useEffect(()=>{},[]),中的依賴參數同等效果,我們在封裝組件時可以用到,具體看代碼

類組件:

class List extends React.Component {
   state = {
      list: []
   }
   static getDerivedStateFromProps(props, state) {
      if(props.list !== state.list){
         return {
            list: props.list
         }
      }
      return null;
   }
   render() {
        .... // 展示 list
   }
}

函數組件:

// 函數組件
const List  = React.memo((props) =>{
   const [list,setList] = React.useState([]);

   React.useEffect(()=>{
      setList(props.list);
   }, [props.list]);

   return (
      .... // 展示 list
   )

});

 2、getSnapshotBeforeUpdate(prevProps,prevState)

  • 替換componentWillUpdate函數,將參數返回並傳遞給componentDidUpdate周期函數
  • getSnapshotBeforeUpdate() 在最近一次渲染輸出(提交到 DOM 節點)之前調用。它使得組件能在發生更改之前從 DOM 中捕獲一些信息(例如,滾動位置)。此生命周期的任何返回值將作為參數傳遞給 componentDidUpdate()
  • 此用法並不常見,但它可能出現在 UI 處理中,如需要以特殊方式處理滾動位置的聊天線程等。
class ScrollingList extends React.Component {
  constructor(props) {
    super(props);
    this.listRef = React.createRef();
  }

  getSnapshotBeforeUpdate(prevProps, prevState) {
    // 我們是否在 list 中添加新的 items ?
    // 捕獲滾動​​位置以便我們稍后調整滾動位置。
    if (prevProps.list.length < this.props.list.length) {
      const list = this.listRef.current;
      return list.scrollHeight - list.scrollTop;
    }
    return null;
  }

  componentDidUpdate(prevProps, prevState, snapshot) {
    // 如果我們 snapshot 有值,說明我們剛剛添加了新的 items,
    // 調整滾動位置使得這些新 items 不會將舊的 items 推出視圖。
    //(這里的 snapshot 是 getSnapshotBeforeUpdate 的返回值)
    if (snapshot !== null) {
      const list = this.listRef.current;
      list.scrollTop = list.scrollHeight - snapshot;
    }
  }

  render() {
    return (
      <div ref={this.listRef}>{/* ...contents... */}</div>
    );
  }
}

繼續完善。。。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM