1.生命周期钩子函数(旧)
1.1 组件挂载
import React from 'react'
class App extends React.Component {
constructor(props) {
super(props)
console.log('constructor')
}
//初始化状态
state = {
count: 0,
}
add = () => {
let { count } = this.state
this.setState({
count: ++count,
})
}
// 組件挂在之前執行
componentWillMount(){
console.log('componentWillMount')
}
// 组件挂载之后执行
componentDidMount(){
console.log('componentDidMount');
}
render() {
console.log('render');
return (
<div>
<h2>count当前的值:{this.state.count}</h2>
<button onClick={this.add}>+</button>
</div>
)
}
}
export default App
:::success 页面初始化阶段: 由ReactDOM.render()触发 ——初次渲染
- constructor
- componentWillMount
- render
- componentDidMount
:::
1.2组件更新
```javascript import React from ‘react’ class App extends React.Component { constructor(props) { super(props) console.log(‘constructor’) } //初始化状态 state = { count: 0, } add = () => { let { count } = this.state this.setState({
}) } // 卸载组件的方法 death = () => { // React.unmountComponentAtNode(document.getElementById(‘app’)); } // 組件挂在之前執行 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’) } render() { console.log(‘render’); return (count: ++count,
) } } export default App<div id='app'>
<h2>count当前的值:{this.state.count}</h2>
<button onClick={this.add}>+</button>
<button onClick={this.death}>卸载组件</button>
</div>
:::success
**页面更新阶段:**由组件内部this.setSate()或父组件重新render触发,且shouldComponentUpdate返回true, 则执行顺序为:
- **shouldComponentUpdate(nextProps, nextState)**
- **componentWillUpdate**
- **render**
- **componentDidUpdate**
:::
**注意:**
- 如果shouldComponentUpdate返回false,则不执行下面的钩子函数;
- 如果组件中不屑shouldComponentUpdate,那么组件会默认的加这个钩子, 且返回值是true;
<a name="tXD17"></a>
## 1.3强制更新组件
```javascript
import React from 'react'
class App extends React.Component {
constructor(props) {
super(props)
console.log('constructor')
}
//初始化状态
state = {
count: 0,
}
add = () => {
let { count } = this.state
this.setState({
count: ++count,
})
}
// 卸载组件的方法
death = () => {
// React.unmountComponentAtNode(document.getElementById('app'));
}
//强制更新组件
force = () => {
console.log('强制更新');
this.forceUpdate()
}
// 組件挂在之前執行
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')
}
render() {
console.log('render');
return (
<div id='app'>
<h2>count当前的值:{this.state.count}</h2>
<button onClick={this.add}>+</button>
<button onClick={this.death}>卸载组件</button>
<button onClick={this.force}>强制刷新页面</button>
</div>
)
}
}
export default App
:::success 强制更新:forceUpdate()
- componentWillUpdate
- render
-
1.4 componentWillReceiveProps:
componentWillReceiveProps在初始的时候不会被调用, 它在组件接收到新的props时调用。 一般用于父组件更新状态时子组件重新渲染。
在React6.3之前,componentWillReceiveProps是在不进行额外render的前提下,相应props中改变并更新state的唯一方式。componentWillReceiveProps(nextProps){
//通过this.props来获取旧的外部状态, 初始props不会被调用
//通过对比新旧状态, 来判断是否执行其他方法
}
2. 生命周期钩子函数(新)
2.1 新版本中废弃掉3个旧版本的钩子函数:
componentWillMount
- componentWillUpdate
- componentWillReceiveProps
注意:现在使用会出现警告, 下一个版本需要加上UNSAFE_前缀才能使用, 以后会彻底废弃, 不建议使用。
2.2 getDerivedStateFromProps:
getDerivedStateFromProps(props, state): 会在调用render方法之前调用, 并且在初始挂载及后续更新时都会被调用, 它应该返回一个对象来更新state, 如果返回null则不更新任何内容。
此方法使用场景:state的值在任何时候都取决于props.
static getDerivedStateFromProps(props, state){
}
2.3 getSnapShotBeforeUpdate():
getSnapShotBeforeUpdate(prevProps, prevState): 在最近一次渲染输出(提交到DOM节点)之前调用。 它使得组件在发生改变之前从DOM中捕获一些信息(例如: 滚动位置)。此生命周期方法的任何返回值将作为参数传递给componentDidUpdate
import React from 'react';
import './index.css'
class Home extends React.Component {
constructor(props){
super(props)
console.log('count:constructor ');
}
state = {
newsArr:[]
}
componentDidMount(){
setInterval(() => {
const { newsArr } = this.state;
//模拟一条新闻
const news = '新闻'+(newsArr.length + 1)
//更新状态
this.setState({
newsArr:[news, ...newsArr]
})
},1000)
}
//组件更新前
getSnapshotBeforeUpdate(){
return this.list.scrollHeight
}
//组件已经更新
componentDidUpdate(prevProps, prevState,height){
console.log('count:componentDidUpdate', height);
this.list.scrollTop += this.list.scrollHeight - height
}
render() {
const { newsArr } = this.state;
console.log('count:render' )
return (
<ul className='list' ref={ c => this.list = c}>
{
newsArr?.map( (item ,index) => {
return <li key={index} className='listItem'>{item}</li>
})
}
</ul>
);
}
}
export default Home;
2.4 新版生命周期钩子函数的三个阶段:
1. 初始化阶段: 由ReactDOM.render()触发——初次渲染 :::success
- constructor()
- getDerivedStateFromProps
- render()
componentDidMount() ::: 2. 更新阶段: 由组件内部的this.setState()或父组件重新render触发 :::success
getDerivedStateFromProps
- shouldComponentUpdate()
- render()
- getSnapshotBeforeUpdate()
- componentDidUpdate
:::
3. 卸载组件: 由ReactDOM.unmountComponentAtNode()触发
:::success
componentWillUnmonunt()
:::
3. 总结
总结:有三个重要的钩子:
1. render: 初始化渲染或者组件更新调用
2. componentDIdMount: 开始监听, 发送Ajax请求
3. componentWillUnmount: 做一些收尾工作: 比如清理定时器;