react新版本生命周期


給componentWillMount componentWillReceiveProps componentWillUpdate生命周期加上UNSAFE_前綴,表明其不安全性,並將在未來版本將其移除

官網文檔指出使用這些生命周期的代碼會在未來版本的react中更容易產生bug,尤其是對於異步渲染的版本 新增生命周期static getDerivedStateFromProps(prevProps, prevState)、getSnapshotBeforeUpdate(prevProps, prevState) 、componendDidCatch(error, info) 
static getDerivedStateFromProps(prevProps, prevState) 在每次渲染之前都會調用,不管造成重新渲染的原因,不管初始掛載還是后面的更新都會調用,這一點和UNSAFE_componentWillReceiveProps不同(只有當父組件造成重新渲染時才調用),每次都應該返回一個對象作為state的更新,或者返回null表示不更新 它的使用場景一般為依賴於props的變化去做一些狀態的更新,讓我們能夠根據props的變化去更新內部的狀態,以前我們經常在componentWillReceiveProps中完成該操作 但是你需要考慮是否真的有必要使用這個生命周期,比如: 如果你需要根據網絡請求獲取數據,你可以在componentDidUpdate里完成 當props改變時,你需要去重新計算某些數據,可以使用memoization helper替代 當props改變時,如果你想要重置一些state,可以考慮使用Fully controlled component(完全移出state的使用,通過父組件控制數據)或者Fully uncontrolled component(數據僅存在內部狀態中)
getSnapshotBeforeUpdate(prevProps,prevState) 在最新的渲染數據提交給DOM前會立即調用,它讓你在組件的數據可能要改變之前獲取他們,他的返回值會被傳遞給componentDidUpdate的第三個參數 componentDidCatch 如果一個組件定義了componentDidCatch生命周期,則他將成為一個錯誤邊界(錯誤邊界會捕捉渲染期間、在生命周期方法中和在它們之下整棵樹的構造函數中的錯誤,就像使用了try catch,不會將錯誤直接拋出了,保證應用的可用性)


class A extends React.Component {
  // 用於初始化 state
  constructor() {}
  // 用於替換 `componentWillReceiveProps` ,該函數會在初始化和 `update` 時被調用
  // 因為該函數是靜態函數,所以取不到 `this`
  // 如果需要對比 `prevProps` 需要單獨在 `state` 中維護
  static getDerivedStateFromProps(nextProps, prevState) {}
  // 判斷是否需要更新組件,多用於組件性能優化
  shouldComponentUpdate(nextProps, nextState) {}
  // 組件掛載后調用
  // 可以在該函數中進行請求或者訂閱
  componentDidMount() {}
  // 用於獲得最新的 DOM 數據
  getSnapshotBeforeUpdate() {}
  // 組件即將銷毀
  // 可以在此處移除訂閱,定時器等等
  componentWillUnmount() {}
  // 組件銷毀后調用
  componentDidUnMount() {}
  // 組件更新后調用
  componentDidUpdate() {}
  // 渲染組件函數
  render() {}
  // 以下函數不建議使用
  UNSAFE_componentWillMount() {}
  UNSAFE_componentWillUpdate(nextProps, nextState) {}
  UNSAFE_componentWillReceiveProps(nextProps) {}
}
 
         

getDerivedStateFromProps內部不可以有副作用,因為現在是無論是state改變還是props改變,

都會執行它。

例如:

這種寫法會導致多次循環渲染直到報錯

class App extends Component { constructor(props){ super(props) this.myFetch=this.myFetch.bind(this) this.state = { name: "", list: null, myFetch:this.myFetch }; } static getDerivedStateFromProps(props, state) { if ( props.name !== state.name ) { // 這一句是有副作用的,它會改變state狀態, // 然后再次調用getDerivedStateFromProps,再次改變state狀態... state.myFetch(props.name) return { name: props.name }; } return null; } myFetch(){ this.setState({ list: "newList" }) } render() { return ( <div>{this.state.list}</div> ); } } 

以上正確寫法應為:

class App extends Component { constructor(props){ super(props) this.myFetch=this.myFetch.bind(this) this.state = { name: "", list: null, //myFetch:this.myFetch }; } // 純函數,無副作用 static getDerivedStateFromProps(props, state) { if ( props.name !== state.name ) { return { name: props.name, list: null }; } return null; } componentDidUpdate(){ if(!this.state.list){ this.myFetch(this.props.name) } } // 看是否需要初始化的時候調用 componentDidMount(){ this.myFetch(this.props.name) } myFetch(){ this.setState({ list: "newList" }) } render() { return ( <div>{this.state.list}</div> ); } }
 

 


免責聲明!

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



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