日本免费高清视频-国产福利视频导航-黄色在线播放国产-天天操天天操天天操天天操|www.shdianci.com

學無先后,達者為師

網站首頁 編程語言 正文

React組件的生命周期深入理解分析_React

作者:花鐺 ? 更新時間: 2022-12-28 編程語言

組件從創建到銷毀的過程,被稱為組件的生命周期。

在生命周期的各個階段都有相對應的鉤子函數,會在特定的時機被調用,被稱為組件的生命周期鉤子。

生命周期回調函數 = 生命周期鉤子函數 = 生命周期函數 = 生命周期鉤子

函數式組件沒有生命周期,因為生命周期函數是 React.Component 類的方法實現的,函數式組件沒有繼承 React.Component,所以也就沒有生命周期。

<-- 容器!-->
<div id="test"></div>
// 創建組件
class Life extends React.Component{
	state = {opacity:1}
	// 調用時機:組件掛載完畢
	componentDidMount(){
		this.timer = setInterval(() => {
			let {opacity} = this.state
			opacity -= 0.1
			if(opacity <= 0) opacity = 1
			this.setState({opacity})
		}, 200);
	}
	//調用時機:組件將要卸載
	componentWillUnmount(){
		clearInterval(this.timer)
	}
	handleUnmount = ()=>{
		//卸載組件
		ReactDOM.unmountComponentAtNode(document.getElementById('test'))
	}
	//調用時機:初始化渲染、狀態更新之后
	render(){
		return(
			<div>
				<h2 style={{opacity:this.state.opacity}}>我是一段透明度會變化的文字</h2>
				<button onClick={this.handleUnmount}>點擊卸載</button>
			</div>
		)
	}
}
//渲染組件
ReactDOM.render(<Life/>,document.getElementById('test'))

生命周期鉤子(新)

新的生命周期鉤子增加了 getDerivedStateFromProps 和 getSnapshotBeforeUpdate。

constructor():constructor() 構造函數在 React 組件掛載之前被調用。

如果不初始化 state 或不為事件處理函數綁定實例,則不需要寫 constructor()。

不能在 constructor() 構造函數內部調用 this.setState(), 因為此時第一次 render() 還未執行,也就意味 DOM 節點還未掛載。

static getDerivedStateFromProps(nextProps, prevState):在每次調用 render() 方法之前都會被調用,在初始化和更新時都會被調用。

getDerivedStateFromProps() 第一個參數為即將更新的 props,第二個參數為上一個狀態的 state,可以比較 props 和 state 來加一些限制條件,防止無用的 state 更新。

getDerivedStateFromProps() 的返回值是必須的。返回一個對象來更新 state,如果不需要更新,返回 null 即可。 getDerivedStateFromProps() 適用于 state 的值在任何時候都取決于 props 的情況。 getDerivedStateFromProps() 是一個靜態函數,是放在組件身上的,而不是放在組件實例身上,因此不能使用 this。

// 之前使用 componentWillReceiveProps
componentWillReceiveProps(nextProps) {
    if (nextProps.location.search !== this.props.location.search) {
    	this.init()
    }
}
// 現在使用 getDerivedStateFromProps:相當于把 componentWillReceiveProps 拆分成 getDerivedStateFromProps 和 componentDidUpdate
static getDerivedStateFromProps(nextProps, prevState) {
  const {search} = nextProps.location
  if (search !== prevState.search) {
    return {
      search,
    }
  }
  return null
}
componentDidUpdate(prevProps, prevState) {
  const {search} = this.state
   if (search !== prevState.search) {
    this.init()
  }
}

render():render() 方法是類組件中唯一必須實現的方法,用于渲染 DOM,render() 方法必須返回 reactDOM。

在 render() 的 return 之前不能寫 setState,否則會觸發死循環導致內存崩潰;return 體里面是可以寫的。

// Wrong
render(){
	this.setState({...})
	return (...)
}
// Correct
render(){
	return (
		<input onClick={()=>this.setState({...})} />
   )
}

componentDidMount():在組件掛載后 (插入 DOM 樹后) 立即調用,此生命周期是發送網絡請求、開啟定時器、訂閱消息等的好時機,并且可以在此鉤子函數里直接調用 setState()。

shouldComponentUpdate(nextProps, nextState):在組件更新之前調用,可以控制組件是否進行更新, 返回 true 時組件更新, 返回 false 則不更新。不寫此生命周期鉤子時默認為 true。

shouldComponentUpdate() 第一個參數是即將更新的 props 值,第二個參數是即將更新后的 state 值,可以根據更新前后的 props 或 state 來比較加一些限制條件,決定是否更新,進行性能優化。

不要在 shouldComponentUpdate 中調用 setState(),否則會導致無限循環調用更新、渲染,直至瀏覽器內存崩潰。

getSnapshotBeforeUpdate(prevProps, prevState):在最新的渲染數據提交給 DOM 前會調用,也就是說,在 render 之后,在 componentDidUpdate 之前調用。使得組件可以在更新之前獲取快照值。不常用。

它可以使組件在 DOM 真正更新之前捕獲一些信息(例如滾動位置),此生命周期返回的任何值都會作為參數傳遞給 componentDidUpdate(),如不需要傳遞任何值,那么返回 null。返回值是必須的。

componentDidUpdate(prevProps, prevState, snapshot):componentDidUpdate() 會在更新后會被立即調用。首次渲染不會執行。

包含三個參數,第一個是上一次props值。 第二個是上一次state值,第三個是“snapshot” 參數傳遞。

可以進行前后 props 的比較進行條件語句的限制,來進行 setState() , 否則會導致死循環。

componentWillUnmount():componentWillUnmount() 在組件即將被卸載或銷毀時進行調用。此生命周期是清理定時器、取消訂閱等操作的好時機。

組件的掛載流程:

  • constructor
  • getDerivedStateFromProps
  • render
  • componentDidMount

setState 更新流程:

  • getDerivedStateFromProps
  • shouldComponentUpdate
  • render
  • getSnapshotBeforeUpdate
  • componentDidUpdate

組件的卸載流程: componentWillUnmount

生命周期鉤子(舊)

React 從 v16.3 開始廢棄 componentWillMount、componentWillReceiveProps、componentWillUpdate 三個鉤子函數。在新版本中使用需要加上 UNSAFE_ 前綴,否則會觸發控制臺的警告。

UNSAFE 不是指安全性,而是表示使用這些生命周期的代碼在 React 的未來版本中更有可能出現 Bug,尤其是在啟用異步渲染之后。

組件的掛載流程:

  • constructor
  • componentWillMount
  • render
  • componentDidMount

setState 更新流程:

  • shouldComponentUpdate
  • componentWillUpdate(組件更新之前調用)
  • render
  • componentDidUpdate

forceUpdate 強制更新流程:

  • componentWillUpdate(組件更新之前調用)
  • render
  • componentDidUpdate

父組件 render 之后子組件的更新流程:

  • componentWillReceiveProps(子組件接收到新的 props 之前調用,第一次接收到 props 不會調用)
componentWillReceiveProps(nextProps) {
	// 可以和 this.props 中的數據進行對比,以決定是否要執行某些方法
}
  • shouldComponentUpdate
  • componentWillUpdate(組件更新之前調用)
  • render
  • componentDidUpdate

組件的卸載流程:

componentWillUnmount

父子組件生命周期

當子組件自身的 state 狀態改變,不會對父組件產生副作用的情況下,父組件不會進行更新,也就是不會觸發父組件的生命周期。

當父組件狀態變化時(不會是否更改到傳給子組件的 props),會觸發自身和子組件對應的生命周期。

render 以及 render 之前的生命周期,父組件先執行;

render 之后的生命周期,子組件先執行,并且是與父組件交替執行。

父子組件初始化流程:

  • 父組件constructor
  • 父組件getDerivedStateFromProps
  • 父組件render
  • 子組件constructor
  • 子組件getDerivedStateFromProps
  • 子組件render
  • 子組件componentDidMount
  • 父組件componentDidMount

子組件修改自身的 state 狀態流程:

  • 子組件getDerivedStateFromProps
  • 子組件shouldComponentUpdate
  • 子組件render
  • 子組件getSnapshotBeforeUpdate
  • 子組件componentDidUpdate

父組件修改 state 狀態流程:

  • 父組件getDerivedStateFromProps
  • 父組件shouldComponentUpdate
  • 父組件render
  • 子組件getDerivedStateFromProps
  • 子組件shouldComponentUpdate
  • 子組件render
  • 子組件getSnapshotBeforeUpdate
  • 父組件getSnapshotBeforeUpdate
  • 子組件componentDidUpdate
  • 父組件componentDidUpdate

父組件卸載子組件:

// 通過點擊父組件中的 [卸載 / 掛載子組件] 按鈕來卸載子組件
handelToggle = () => {
    this.setState({
      isHidden: !this.state.isHidden
    })
  }
<button onClick={this.handelToggle}>掛載/卸載子組件</button>
{this.state.isHidden ? '' : <Child />>}
  • 父組件getDerivedStateFromProps
  • 父組件shouldComponentUpdate
  • 父組件render
  • 父組件getSnapshotBeforeUpdate
  • 子組件componentWillUnmount
  • 組件componentDidUpdate

父組件重新掛載子組件:

再次點擊父組件中的 [卸載 / 掛載子組件] 按鈕來掛載子組件。

  • 父組件getDerivedStateFromProps
  • 父組件shouldComponentUpdate
  • 父組件render
  • 子組件constructor
  • 子組件getDerivedStateFromProps
  • 子組件render
  • 父組件getSnapshotBeforeUpdate
  • 子組件componentDidMount
  • 父組件componentDidUpdate

原文鏈接:https://blog.csdn.net/wsln_123456/article/details/109201826

欄目分類
最近更新