react生命週期

組件的生命週期可分成三個狀態:

  • Mounting:已插入真實 DOM
  • Updating:正在被重新渲染
  • Unmounting:已移出真實 DOM

生命週期的方法有:

componentWillMount 

在渲染前調用,在客戶端也在服務端。一般用的比較少,更多的是用在服務端渲染

1、組件剛經歷constructor,初始完數據
2、組件還未進入render,組件還未渲染完成,dom還未渲染

componentDidMount 

在第一次渲染後調用,只在客戶端。之後組件已經生成了對應的DOM結構,可以通過this.getDOMNode()來進行訪問。 如果你想和其他JavaScript框架一起使用,可以在這個方法中調用setTimeout, setInterval或者發送AJAX請求等操作(防止異步操作阻塞UI)。

組件第一次渲染完成,此時dom節點已經生成,可以在這裏調用ajax請求,返回數據setState後組件會重新渲染

componentWillReceiveProps 

在組件接收到一個新的 prop (更新後)時被調用。這個方法在初始化render時不會被調用。

shouldComponentUpdate 

返回一個布爾值。在組件接收到新的props或者state時被調用。在初始化時或者使用forceUpdate時不被調用。 
可以在你確認不需要更新組件時使用。

componentWillUpdate

在組件接收到新的props或者state但還沒有render時被調用。在初始化時不會被調用。

componentDidUpdate

 在組件完成更新後立即調用。在初始化時不會被調用。

componentWillUnmount

在組件從 DOM 中移除之前立刻被調用。

class Demo extends Component {
  	constructor(props, context) {
      	    //如果想(在組件其他地方是可以直接接收的)使用props或context,則需要以參數形式傳入。
      	    //只要組件存在constructor,就必要要寫super,否則this指向會錯誤
      	    super(props, context);
      	    this.state = {
          	    data: 1
      	    };
  	},
	componentWillMount () {
		// 在組件掛載之前調用,且全局只調用一次。如果在這個鉤子裏可以setState,render後可以看到更新後的state,不會觸發重複渲染。
		// 該生命週期可以發起異步請求,並setState。(React v16.3後廢棄該生命週期,可以在constructor中完成設置state)
		// 不推薦在這裏發起ajax請求,若返回數據爲空,則容易造成界面空白,影響渲染效果
	},
	componentDidMount () {
		//組件第一次渲染完成,此時dom節點已經生成,可以在這裏調用ajax請求,返回數據setState後組件會重新渲染
	},
	componentWillReceiveProps (nextProps) {
		// 在接受父組件改變後的props需要重新渲染組件時用到的比較多
		// 通過對比nextProps和this.props,將nextProps setState爲當前組件的state,從而重新渲染組件
		nextProps.data !== this.props.data && this.setState({
	        data: nextProps.data
		    },() => {
		      console.log("new data...");
	  	});

	},
	shouldComponentUpdate (nextProps, nextState) {
		// react性能優化非常重要的一環。
		// 組件接受新的state或者props時調用,我們可以設置在此對比前後兩個props和state是否相同,
		// 如果相同則返回false阻止更新,因爲相同的屬性狀態一定會生成相同的dom樹,
		// 這樣就不需要創造新的dom樹和舊的dom樹進行diff算法對比,節省大量性能,尤其是在dom結構複雜的時候。
	},
	componentWillUpdate (nextProps, nextState) {
		// 組件初始化時不調用,只有在組件發生更新需要重新渲染時才調用
	},
	componentDidUpdate (prevProps, prevState) {
		// 組件初始化時不調用,組件更新渲染完成後調用,此時dom節點加載完成,可以獲取到dom節點。
		// react只會在第一次初始化成功會進入componentDidmount,
		// 之後每次重新渲染後都會進入這個生命週期,這裏可以拿到prevProps和prevState,即更新前的props和state。
		// 該鉤子內setState有可能會觸發重複渲染,需要謹慎判斷,否則會進入死循環 
	},
	render () {
	    return (
	        <div>This is Demo!</div>
	    );
	},
	componentWillUnmount () {
		// 組件將要卸載時調用,一些事件監聽和定時器需要在此時清除。
	},
	componentDidCatch (error, info) {
    	//React 16 中引入,用來 捕獲組件的錯誤。
    	//如果 render() 函數拋出錯誤,則會觸發該函數。
    	//錯誤在渲染階段中被捕獲,但在事件處理程序中不會被捕獲。
    }
}

 

TIPS: 在生命週期中的哪一步你應該發起 AJAX 請求?

我們應當將AJAX 請求放到 componentDidMount 函數中執行,主要原因有下:

  • React 可能會多次頻繁調用 componentWillMount,如果我們將 AJAX 請求放到 componentWillMount 函數中,那麼顯而易見其會被觸發多次,自然也就不是好的選擇。

  • 如果我們將 AJAX 請求放置在生命週期的其他函數中,我們並不能保證請求僅在組件掛載完畢後纔會要求響應。如果我們的數據請求在組件掛載之前就完成,並且調用了setState函數將數據添加到組件狀態中,對於未掛載的組件則會報錯。而在 componentDidMount 函數中進行 AJAX 請求則能有效避免這個問題。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章