在React中,生命週期函數指的是元件在某一個時刻會自動執行的函數
在類或元件建立的時候被自動執行,我們可以說它是生命週期函數,但它並不是React所特有的,所有的Es6物件都有這個函數,所以並不能說它是React的生命週期函數
當資料發生變化時,render函數會被自動執行,符合我們對React生命週期函數的定義,所以它是React的生命週期函數,但在初始階段,並不會有任何的React生命週期函數被執行,但會執行constructor建構函式,進行元件資料的初始化、
import React,{Component} from 'react'; class Demo extends Component{ constructor(props){ console.log("初始化資料..."); super(props); this.state = {}; } render(){ return ( <div>Hello World</div> ); } } export default Demo
頁面掛載階段,UNSAFE_componentWillMount 頁面即將render掛載在html前執行,以前叫做componentWillMount但React團隊認為這些生命週期函數經常被誤解和巧妙的濫用,會帶來潛在的問題,所以為他們加上了UNSAFE_字首,當然這裡的不安全不是指安全性,而是表示使用這些周期函數在未來的React版本中更有可能出現錯誤。即將掛載的函數執行完畢,會進行渲染掛載render,之後會執行componentDidMount函數,我們可以把完成掛載後的邏輯寫在這個函數上。記住,只有元件第一次渲染頁面才會執行mount
import React,{Component} from 'react'; class Demo extends Component{ constructor(props){ console.log("初始化資料..."); super(props); this.state = {}; } UNSAFE_componentWillMount(){ console.log('UNSAFE_componentWillMount'); } render(){ console.log('render'); return ( <div>Hello World</div> ); } componentDidMount(){ console.log('componentDidMount'); } } export default Demo
資料更新階段,state或props發生變化,頁面會重新渲染。state會在更新前先執行shouldComponentUpdate生命週期函數,這個函數比較特殊,它需要有一個返回值,true或者false,控制頁面是否需要重新重新渲染,如果僅僅是資料發生變化,我們可以返回false,那麼之後的生命週期函數都不會執行,這樣可以有效的提升我們元件更新的效率。返回true後,會執行UNSAFE_componentWillUpdate函數做更新前的準備,在執行render進行頁面的重新渲染,渲染完畢後執行componentDidUpdate函數
import React,{Component} from 'react'; class Demo extends Component{ constructor(props){ console.log("初始化資料..."); super(props); this.handleClickTest = this.handleClickTest.bind(this); this.state = { number:1 }; } handleClickTest(){ const number = this.state.number + 1; this.setState({ number }); } UNSAFE_componentWillMount(){ console.log('UNSAFE_componentWillMount'); } render(){ console.log('render'); return ( <div onClick={this.handleClickTest}>Hello World</div> ); } componentDidMount(){ console.log('componentDidMount'); } //更新前執行 shouldComponentUpdate(){ console.log('shouldComponentUpdate'); return true; } UNSAFE_componentWillUpdate(){ console.log('componentWillUpdate'); } componentDidUpdate(){ console.log('componentDidUpdate') } } export default Demo
componentWillReceiveProps生命週期函數,只有一個元件接收props或者說當一個元件是子元件接收props的時候,它才會被執行,所以我們需要定義一個子元件接收父元件傳值
import React,{Component,Fragment} from 'react'; import Demo2 from './Demo2'; class Demo extends Component{ constructor(props){ console.log("初始化資料..."); super(props); this.handleClickTest = this.handleClickTest.bind(this); this.state = { number:1 }; } handleClickTest(){ const number = this.state.number + 1; this.setState({ number }); } UNSAFE_componentWillMount(){ console.log('UNSAFE_componentWillMount'); } render(){ console.log('render'); return ( <Fragment> <div onClick={this.handleClickTest}>Hello World</div> <Demo2 number={this.state.number}/> </Fragment> ); } componentDidMount(){ console.log('componentDidMount'); } //更新前執行 shouldComponentUpdate(){ console.log('shouldComponentUpdate'); return true; } UNSAFE_componentWillUpdate(){ console.log('componentWillUpdate'); } componentDidUpdate(){ console.log('componentDidUpdate') } //元件從頁面中移除前自動執行 componentWillUnmount(){ } } export default Demo
子元件Demo2
import React,{Component} from 'react'; class Demo2 extends Component{ componentWillReceiveProps(){ console.log('componentWillReceiveProps'); } render(){ const {number} = this.props; return (<div>{number}</div>); } } export default Demo2;
當子元件接收引數發生變化時,就會執行componentWillReceiveProps函數,然後執行shouldComponentUpdate函數,返回值為true時依次執行componentWillUpdate,render,componentDidUpdate
當元件從頁面移除時自動執行componentWillUnmount函數,我們先定義一個路由
import React from 'react'; import ReactDom from 'react-dom'; import TodoList from './TodoList'; import {BrowserRouter,Routes,Route} from 'react-router-dom'; import ButtonTest from './ButtonTest'; import NewButton from './NewButton'; import Demo from './Demo'; class Entry extends React.Component{ render(){ return ( <BrowserRouter> <Routes> {/*{<Route path='/todoList' element={<TodoList/>}/>}*/} {<Route path='/buttonTest' element={<ButtonTest/>}/>} {<Route path='/newButton' element={<NewButton/>}/>} <Route path='/Demo' element={<Demo/>}/> </Routes> </BrowserRouter> ) } } ReactDom.render(<Entry/>,document.getElementById('root'));
從button元件跳轉到list元件,button從頁面移除時可觀察到自動執行了componentWillUnmount函數
import React,{Component} from 'react'; import { Button } from 'antd'; import {Link} from 'react-router-dom'; class NewButton extends Component{ render(){ return ( <Link to='/buttonTest'> <Button type="primary">Primary</Button> </Link> ); } //元件從頁面中移除前自動執行 componentWillUnmount(){ console.log('componentWillUnmount-----------'); } } export default NewButton;
import React,{Component} from 'react'; import { List, Avatar } from 'antd'; const data = [ { title: 'Ant Design Title 1', }, { title: 'Ant Design Title 2', }, { title: 'Ant Design Title 3', }, { title: 'Ant Design Title 4', }, ]; class ButtonTest extends Component{ render(){ return ( <List itemLayout="horizontal" dataSource={data} renderItem={item => ( <List.Item> <List.Item.Meta avatar={<Avatar src="https://zos.alipayobjects.com/rmsportal/ODTLcjxAfvqbxHnVXCYX.png" />} title={<a href="https://ant.design">{item.title}</a>} description="Ant Design, a design language for background applications, is refined by Ant UED Team" /> </List.Item> )} /> ); } } export default ButtonTest;
執行結果