前言: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> ); } }
繼續完善。。。