对生命周期的理解
组件从创建到死亡它会经历一些特定的阶段。
React组件中包含一系列勾子函数(生命周期回调函数), 会在特定的时刻调用。
我们在定义组件时,会在特定的生命周期回调函数中,做特定的工作。
生命周期(旧)
生命周期流程图(旧)

生命周期的三个阶段(旧)
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| 1. 初始化阶段: 由ReactDOM.render()触发---初次渲染 1. constructor() 2. componentWillMount() 3. render() 4. componentDidMount() =====> 常用 一般在这个钩子中做一些初始化的事,例如:开启定时器、发送网络请求、订阅消息 2. 更新阶段: 由组件内部this.setSate()或父组件render触发 1. shouldComponentUpdate() 2. componentWillUpdate() 3. render() =====> 必须使用的一个 4. componentDidUpdate() 3. 卸载组件: 由ReactDOM.unmountComponentAtNode()触发 1. componentWillUnmount() =====> 常用 一般在这个钩子中做一些收尾的事,例如:关闭定时器、取消订阅消息
|
案例
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
| class Count extends React.Component{
constructor(props){ console.log('Count---constructor'); super(props) this.state = {count:0} }
add = ()=>{ const {count} = this.state this.setState({count:count+1}) }
death = ()=>{ ReactDOM.unmountComponentAtNode(document.getElementById('test')) }
force = ()=>{ this.forceUpdate() }
componentWillMount(){ console.log('Count---componentWillMount'); }
componentDidMount(){ console.log('Count---componentDidMount'); }
componentWillUnmount(){ console.log('Count---componentWillUnmount'); }
shouldComponentUpdate(){ console.log('Count---shouldComponentUpdate'); return true }
componentWillUpdate(){ console.log('Count---componentWillUpdate'); }
componentDidUpdate(){ console.log('Count---componentDidUpdate'); }
render(){ console.log('Count---render'); const {count} = this.state return( <div> <h2>当前求和为:{count}</h2> <button onClick={this.add}>点我+1</button> <button onClick={this.death}>卸载组件</button> <button onClick={this.force}>不更改任何状态中的数据,强制更新一下</button> </div> ) } } class A extends React.Component{ state = {carName:'奔驰'}
changeCar = ()=>{ this.setState({carName:'奥拓'}) }
render(){ return( <div> <div>我是A组件</div> <button onClick={this.changeCar}>换车</button> <B carName={this.state.carName}/> </div> ) } } class B extends React.Component{ componentWillReceiveProps(props){ console.log('B---componentWillReceiveProps',props); }
shouldComponentUpdate(){ console.log('B---shouldComponentUpdate'); return true } componentWillUpdate(){ console.log('B---componentWillUpdate'); }
componentDidUpdate(){ console.log('B---componentDidUpdate'); }
render(){ console.log('B---render'); return( <div>我是B组件,接收到的车是:{this.props.carName}</div> ) } } ReactDOM.render(<Count/>,document.getElementById('test'))
|
生命周期(新)
生命周期流程图(新)

生命周期的三个阶段(新)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| 1. 初始化阶段: 由ReactDOM.render()触发---初次渲染 1. constructor() 2. getDerivedStateFromProps 3. render() 4. componentDidMount() =====> 常用 一般在这个钩子中做一些初始化的事,例如:开启定时器、发送网络请求、订阅消息 2. 更新阶段: 由组件内部this.setSate()或父组件重新render触发 1. getDerivedStateFromProps 2. shouldComponentUpdate() 3. render() 4. getSnapshotBeforeUpdate 5. componentDidUpdate() 3. 卸载组件: 由ReactDOM.unmountComponentAtNode()触发 1. componentWillUnmount() =====> 常用 一般在这个钩子中做一些收尾的事,例如:关闭定时器、取消订阅消息
|
案例
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
| class Count extends React.Component{ constructor(props){ console.log('Count---constructor'); super(props) this.state = {count:0} }
add = ()=>{ const {count} = this.state this.setState({count:count+1}) }
death = ()=>{ ReactDOM.unmountComponentAtNode(document.getElementById('test')) }
force = ()=>{ this.forceUpdate() } static getDerivedStateFromProps(props,state){ console.log('getDerivedStateFromProps',props,state); return null }
getSnapshotBeforeUpdate(){ console.log('getSnapshotBeforeUpdate'); return 'atguigu' }
componentDidMount(){ console.log('Count---componentDidMount'); }
componentWillUnmount(){ console.log('Count---componentWillUnmount'); }
shouldComponentUpdate(){ console.log('Count---shouldComponentUpdate'); return true }
componentDidUpdate(preProps,preState,snapshotValue){ console.log('Count---componentDidUpdate',preProps,preState,snapshotValue); } render(){ console.log('Count---render'); const {count} = this.state return( <div> <h2>当前求和为:{count}</h2> <button onClick={this.add}>点我+1</button> <button onClick={this.death}>卸载组件</button> <button onClick={this.force}>不更改任何状态中的数据,强制更新一下</button> </div> ) } } ReactDOM.render(<Count count={199}/>,document.getElementById('test'))
|
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
| class NewsList extends React.Component{
state = {newsArr:[]}
componentDidMount(){ setInterval(() => { const {newsArr} = this.state const news = '新闻'+ (newsArr.length+1) this.setState({newsArr:[news,...newsArr]}) }, 1000); }
getSnapshotBeforeUpdate(){ return this.refs.list.scrollHeight }
componentDidUpdate(preProps,preState,height){ this.refs.list.scrollTop += this.refs.list.scrollHeight - height }
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'))
|
重要的钩子
render:初始化渲染或更新渲染调用
componentDidMount:开启监听, 发送ajax请求
componentWillUnmount:做一些收尾工作, 如: 清理定时器
即将废弃的钩子
componentWillMount
componentWillReceiveProps
componentWillUpdate
现在使用会出现警告,下一个大版本需要加上UNSAFE_前缀才能使用,以后可能会被彻底废弃,不建议使用。