---
# System prepended metadata

title: Life Cycle
tags: [Javascript, React]

---

# Life Cycle
###### tags: `React` `Javascript`
1. 組件從創建到死亡會經歷一些特定階段
2. React組件中包含一系列生命週期回調函數，會在特定時候調用
3. 定義組件時，會在特定的生命週期回調函數中，做特定的工作 

舊版

	<script type="text/babel">
	class Demo extends React.Component {
	
		state = { opacity : 1 }

		dead = ()=>{
			//卸載組件
			ReactDom.unmountComponentAtNode(document.getElementById('target'));
		}

		//父組件傳入一個新的props時調用，初始化頁面時不會調用
		componentWillReceiveProps(props){
		
		}
			
		//組件掛載完成後調用
		componentDidMount(){
			this.timer = setInterval(()=>{
				let {opacity} = this.state;
				opacity -= 0.1;
				if(opacity <= 0) opacity = 1;
				this.setState({opacity});
			},200)
		}
		
		//組件卸載前
		componentWillUnmount(){
			clearInterval(this.timer);
		}
		
		//初始化渲染、狀態更新時調用
		render(){
			return (
				<form>
					<h1>{this.props.pass]</h1>
					<div style={this.state.opacity}>測試</div>
					<button onClick={this.change}>結束</button>
				</form>
			)
		}
		
	}
	
	class DemoFoo extends React.Component {
		state = { test : 1}
	
		change = ()=>{
			const {test} = this.state;
			this.setState({test : test++})
		}
		
		render(){
			return (
				<form>
					<Demo pass={this.state.test} />測試</div>
					<button onClick={this.change}>修改</button>
				</form>
			)
		}
	}
	</script>


掛載流程
1. constructor
2. componentWillMount
3. render
4. componentDidMount
畫面初始化觸發
 
更新流程	
1. componentWillReceiveProps 由父組件觸發
2. shouldComponentUpdate 會判斷是否需要重新render 需要return Boolean 
3. componentWillUpdate
4. render
5. componentDidUpdate

setState (改狀態) : 2 -> 3 -> 4 -> 5 
forceUpdate (強制更新，無法改狀態): 3 -> 4 -> 5 
父組件render時子組件 1 ->  2 -> 3 -> 4 -> 5 

卸載
1. ComponentWillUnmout 卸載
由ReactDom.unmountComponentAtNode() 觸發

新版 17~
因這三個hook在未來異步渲染可能造成重大bug，因此被改為須加上前綴UNSAFE_
才能使用
componentWillMount => UNSAFE_componentWillMount
componentWillUpdate => UNSAFE_componentWillUpdate
componentWillReceiveProps  => UNSAFE_componentWillReceiveProps


掛載流程
1. constructor
2. getDerivedStateFromProps
3. render
4. componentDidMount
畫面初始化觸發
 
更新流程	
1. getDerivedStateFromProps
2. shouldComponentUpdate
3. render
4. getSnapshotBeforeUpdate
5. componentDidUpdate

setState (改狀態) : 1-> 2 -> 3 -> 4 -> 5 
forceUpdate (強制更新，無法改狀態): 1 -> 3 -> 4 -> 5 
父組件render時子組件 1 ->  2 -> 3 -> 4 -> 5 

卸載
1. ComponentWillUnmout 卸載
由ReactDom.unmountComponentAtNode() 觸發

--- 
**方法介紹**
getDerivedStateFromProps : 
需要為static且回傳state obj | null
可傳入一個props及state
若是回傳一個state obj 則狀態不能再被改變，因為在新的生命週期此方法橫跨所有操作，因此狀態會在這邊被攔截
使用時機=>若state的值在任何時候都取決於props則可使用

getSnapshotBeforeUpdate : 
需要回傳snapshot value ( any ) | null
回傳值會傳入componentDidUpdate 
時間點為畫面更新前

componentDidUpdate:
可傳入 preProps , preState ,snapshotValue
時間點為畫面更新後，可搭配snapshotValue使用