React第十五章 lifeCycle

190 阅读2分钟

一、资源

1、组件的生命周期

2、生命周期图谱

二、React V16.3之前的⽣命周期

三、生命周期-更新

V17 可能会废弃的三个生命周期函数用 getDerivedStateFromProps 替代,

⽬前使用的话加上UNSAFE_:

  • componentWillMount
  • componentWillReceiveProps
  • componentWillUpdate

如果不想手动给将要废弃的生命周期添加 UNSAFE_ 前缀,可以用下面的命令

npx react-codemod rename-unsafe-lifecycles <path>

引入两个新的生命周期函数:

1、getDerivedStateFromProps

2、getSnapshotBeforeUpdate

四、getDerivedStateFromProps

getDerivedStateFromProps(props, state)

getDerivedStateFromProps 会在调用 render 方法之前调用,并且在初始挂载及后续更新时都会被调⽤。它应返回一个对象来更新 state ,如果返回 null 则不更新任何内容。

请注意,不管原因是什么,都会在每次渲染前触发此方法。

与UNSAFE_componentWillReceiveProps 形成对比,后者仅在⽗组件重新渲染时触发,而不是在内部调⽤ setState 时。

五、getSnapshotBeforeUpdate

getSnapshotBeforeUpdate(prevProps, prevState)

在render之后,在componentDidUpdate之前。

getSnapshotBeforeUpdate() 在最近⼀次渲染输出(提交到 DOM 节点)之前调用。

它使得组件能在发⽣更改之前从 DOM 中捕获一些信息(例如,滚动位置)。

此生命周期的任何返回值将作为参数传递给 componentDidUpdate(prevProps, prevState, snapshot) 。

六、创建LifeCyclePage.js


import React, { Component } from "react";
import PropTypes from "prop-types";

/* V17可能会废弃的三个生命周期
    函数用getDerivedStateFromProps替代,
    ⽬前使用的话加上 UNSAFE_:
    - componentWillMount
    - componentWillReceiveProps - componentWillUpdate
*/

export default class LifeCyclePage extends Component {
    static defaultProps = { msg: "omg" };
    static propTypes = { msg: PropTypes.string.isRequired };
    
    constructor(props) {
        super(props); this.state = { count: 0, };
        console.log("constructor", this.state.count); 
    }
    
    static getDerivedStateFromProps(props, state) {
        // getDerivedStateFromProps 会在调⽤ render 方法之前调用, 
        // 并且在初始挂载及后续更新时都会被调⽤。
        // 它应返回⼀个对象来更新 state,如果返回 null 则不更新任何内容。 
        return count < 5 ? null : { count: 0 };
    }
    
    // 在render之后,在componentDidUpdate之前。 
    getSnapshotBeforeUpdate(prevProps, prevState, snapshot) {
        const { count } = prevState; 
        console.log("getSnapshotBeforeUpdate", count); 
        return null;
    }
    /* UNSAFE_componentWillMount() {
        //	不推荐,将会被废弃
        console.log("componentWillMount", this.state.count);
    } */
    
    componentDidMount() { 
        console.log("componentDidMount", this.state.count);
    }
    
    componentWillUnmount() {
        //	组件卸载之前
        console.log("componentWillUnmount", this.state.count); 
    }
    
    /* UNSAFE_componentWillUpdate() {
        //	不推荐,将会被废弃
        console.log("componentWillUpdate", this.state.count);
    } */
    
    componentDidUpdate() { 
        console.log("componentDidUpdate", this.state.count);
    }
    
    shouldComponentUpdate(nextProps, nextState) {
        const { count } = nextState; 
        console.log("shouldComponentUpdate", count, nextState.count); 
        return count !== 3;
    }
    
    setCount = () => { 
        this.setState({ count: this.state.count + 1, });
    };
    render() {
        const { count } = this.state; 
        console.log("render", this.state); 
        return<div> 
            <p>{count}</p>
            <button onClick={this.setCount}>改变count</button> 
            {/* {!!(count % 2) && <Foo />} */}
            <Child count={count} />
        </div>
    }
}

class Child extends Component {
    UNSAFE_componentWillReceiveProps(nextProps) {
        //	不推荐,将会被废弃
        // 	UNSAFE_componentWillReceiveProps() 会在已挂载的组件接收新的 props 之前被调用 
        console.log("Foo componentWillReceiveProps");
        }
    componentWillUnmount() {
        //	组件卸载之前
        console.log(" Foo componentWillUnmount"); 
    }
    render() {
        return <div>
            我是Foo组件
            <div> Foo count: {this.props.count}</div>
        </div>
    }
}