组件的生命周期
从出生到成长,最后到死亡,这个过程的时间可以理解为生命周期。React的生命周期同理也是这么一个过程。
React的生命周期分为三个阶段:挂载期(也叫实例化期)、更新期(也叫存在期)、卸载期(也叫销毁期)。在每个周期中React都提供了一些钩子函数。
生命周期的描述如下:
挂载期:一个组件实例初次北创建的过程。
更新期:组件在创建后再次渲染的过程。
卸载期:组件在使用完后被销毁的过程。
旧版本生命周期 16.8.4
1.初始化阶段:由ReactDOM.render()触发
- constructor()
- componentWillMount()
- render()
- componentDidMount()
- 一般做一些初始化 的事情,开启定时器、发送网络请求、订阅消息
2.更新阶段:由组件内部this.setState()或父组件render触发
- shouldComponentUpdate()
- componentWillUpdate()
- render()
- componentDidUpdate()
3.卸载组件:由ReactDOM.unmountComponentAtNode()触发
- componentWillUnmount()
.png)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126
| <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <div id="test"></div> <script type="text/javascript" src="../js/react.development.js"></script> <script type="text/javascript" src="../js/react-dom.development.js"></script> <script type="text/javascript" src="../js/babel.min.js"></script> <script type="text/javascript" src="../js/prop-types.js"></script> <script type="text/babel"> class Count extends React.Component {
constructor(props) { console.log('constructor'); super(props); this.state = {count: 0} }
componentWillMount(){ console.log('componentWillMount'); } componentDidMount(){ console.log('componentDidMount'); } componentWillUnmount(){ console.log('componentWillUnmount'); } shouldComponentUpdate(){ console.log('shouldComponentUpdate'); return true } componentWillUpdate(){ console.log('componentWillUpdate'); } componentDidUpdate(){ console.log('componentDidUpdate'); }
add = () => { const {count} = this.state this.setState({count: count + 1}) } death = () => { ReactDOM.unmountComponentAtNode(document.getElementById('test')) } force = () => { this.forceUpdate() }
render() { console.log('render'); const {count} = this.state return ( <div> <h2>当前求和为:{count}</h2> <button onClick={this.add}>点我+1</button> <button onClick={this.death}>卸载组件+1</button> <button onClick={this.force}>强制更新</button> </div> ) } }
class A extends React.Component{
state = { carName:'奔驰' } changeCar = () => { this.setState({carName:'奥托'}) }
render(){ return( <div> <div>i am A component</div> <button onClick={this.changeCar}>换车</button> <B carName={this.state.carName} /> </div> ) } }
class B extends React.Component{ componentWillReceiveProps(props){ console.log('B----componentWillReceiveProps'); console.log(props); } shouldComponentUpdate(){ console.log('B-------shouldComponentUpdate'); } componentWillUpdate(){ console.log('B-------componentWillUpdate'); } componentDidUpdate(){ console.log('B-------componentDidUpdate'); }
render(){ return( <div>i am b component,接收到的车是:{this.props.carName}</div> ) } }
ReactDOM.render(<A/>, document.getElementById('test')) </script> </body> </html>
|
新版本生命周期 17.0.1
1.初始化阶段:由ReactDOM.render()触发
- constructor()
- getDerivedStateFromProps()
- render()
- componentDidMount()
- 一般做一些初始化 的事情,开启定时器、发送网络请求、订阅消息
2.更新阶段:由组件内部this.setState()或父组件render触发
- getDerivedStateFromProps()
- shouldComponentUpdate()
- render()
- getSnapshotBeforeUpdate()
- componentDidUpdate()
3.卸载组件:由ReactDOM.unmountComponentAtNode()触发
- componentWillUnmount()
.png)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87
| <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <div id="test"></div> <script type="text/javascript" src="../js/17.0.1/react.development.js"></script> <script type="text/javascript" src="../js/17.0.1/react-dom.development.js"></script> <script type="text/javascript" src="../js/17.0.1/babel.min.js"></script> <script type="text/javascript" src="../js/17.0.1/prop-types.js"></script> <script type="text/babel"> class Count extends React.Component {
constructor(props) { console.log('constructor'); super(props); this.state = {count: 0} }
static getDerivedStateFromProps(props,state){ console.log('getDerivedStateFromProps'); return null }
getSnapshotBeforeUpdate(){ console.log('getSnapshotBeforeUpdate'); return 'hello world' }
componentDidMount(){ console.log('componentDidMount'); } componentWillUnmount(){ console.log('componentWillUnmount'); } shouldComponentUpdate(){ console.log('shouldComponentUpdate'); return true } componentDidUpdate(preProps,preState,snapshotValue){ console.log('componentDidUpdate',preProps,preState,snapshotValue); }
add = () => { const {count} = this.state this.setState({count: count + 1}) } death = () => { ReactDOM.unmountComponentAtNode(document.getElementById('test')) } force = () => { this.forceUpdate() }
render() { console.log('render'); const {count} = this.state return ( <div> <h2>当前求和为:{count}</h2> <button onClick={this.add}>点我+1</button> <button onClick={this.death}>卸载组件+1</button> <button onClick={this.force}>强制更新</button> </div> ) } } ReactDOM.render(<Count count="199" />, document.getElementById('test')) </script> </body> </html>
|
getSnapshotBeforeUpdate应用实例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64
| <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <style> .list { width: 200px; height: 150px; background-color: skyblue; overflow: auto; }
.news { height: 30px; } </style> </head> <body> <div id="test"></div> <script type="text/javascript" src="../js/17.0.1/react.development.js"></script> <script type="text/javascript" src="../js/17.0.1/react-dom.development.js"></script> <script type="text/javascript" src="../js/17.0.1/babel.min.js"></script> <script type="text/javascript" src="../js/17.0.1/prop-types.js"></script> <script type="text/babel"> class NewsList extends React.Component {
state = {newsArr:[]}
getSnapshotBeforeUpdate(){ return this.refs.list.scrollHeight }
componentDidUpdate(preProps,preState,height){ this.refs.list.scrollTop += this.refs.list.scrollHeight - height }
componentDidMount(){ setInterval(() => { const {newsArr} = this.state const news = '新闻' + (newsArr.length + 1) this.setState({newsArr:[news,...newsArr]})
},1000) }
render() { return ( <div className="list" ref="list"> {this.state.newsArr.map((n,index) => { return <div key={index} className="news">{n}</div> })} </div> ) } } ReactDOM.render(<NewsList/>,document.getElementById('test')) </script>
</body> </html>
|
重要的钩子
- render():初始化渲染或更新渲染调用
- componentDidMount():开启监听 ,发送ajax请求
- componentWillUnmount():做一些收尾工作:清理定时器
即将废弃的钩子
- componentWillMount
- componentWillReceiveProps
- componentWillUpdate
componentWIllMount() componentWillReceiveProps() componentWillUpdate() 这三个生命周期函数需要加上前缀 UNSAVE_