React 中组件的生命周期

官方生命周期速查表

官方生命周期速查表
注意:速查表上方有个是否显示不常用的生命周期以及react版本和国际化;

类(class)组件生命周期

每个类组件都包含"生命周期方法",实质上是钩子函数,通过重写这些钩子函数,可以帮助我们在特定的契机执行一些动作。
这里记录一下常用的和不常用的生命周期方法,即将过时和过时的生命周期方法不做记录;
注意: React version ≥ 16.4;

import React from 'react';

class Cycle extends React.Component {

    // React 组件挂载之前调用
    constructor(props) {
        // 必须调用 super(props), 否则在构造函数中无法使用 this.props
        super(props);
        // 在 constructor 中,以这种形式初始化 state
        this.state = {
            name: "赵云"
        }
    }

    // 组件挂在之后(插入DOM树中)调用, 此时dom已渲染
    componentDidMount() {
        /**
         * 可以添加一些依赖于 DOM 节点的初始化操作
         * 1. 网络请求获取数据
         * 2. 添加订阅
         * 注意:在此调用 setState(), 将触发额外渲染,但此渲染会发生在浏览器更新屏幕之前,
         *      即使两次调用 render() 用户也不会开到中间状态,值得注意的是这种操作会导致性能问题,
         *      谨慎使用。
         */
        console.log("componentDidMount");
    }

    // 组件更新后调用
    componentDidUpdate(prevProps, prevState, snapshot) {
        /**
         * 如果组件实现了 getSnapshotBeforeUpdate() 生命周期(不常用),则它的返回值将作为
         * componentDidUpdate() 的第三个参数 “snapshot” 参数传递。否则此参数将为 undefined。
         * 
         * 注意:如果 shouldComponentUpdate() 返回值为 false,则不会调用 componentDidUpdate();
         */
        console.log("componentDidUpdate");
    }

    // 组件卸载及销毁之前调用
    componentWillUnmount() {
        /**
         * 可以添加一些必要的清除操作操作
         * 1. 清除 timer
         * 2. 取消订阅
         * 3. 取消网络请求
         * 注意:这里不应该调用 setState() ,因为组件将永远不会重新渲染
         */
        console.log("componentWillUnmount");
    }

    // class 组件中唯一必须实现的方法
    render() {
		// 一个纯渲染函数,返回Dom,React组件,Fragment等
        return null;
    }

    // 通过返回值(true/false)判断是否重新渲染(执行render())
    shouldComponentUpdate(nextProps, nextState) {
        /**
         * 当 props 或 state 发生变化时,会在渲染执行之前被调用,返回 true
         * 则重新渲染,返回 false, 则不渲染,默认返回 true;
         * 1. 性能优化: 根据nextProps, nextState判断是否重新渲染,减少渲染次数;
         * 
         * 注意:首次渲染或使用 forceUpdate() 时不会调用;
         */
        console.log("shouldComponentUpdate");
    }

    // 调用 render 方法之前调用,并且在初始挂载及后续更新时都会被调用
    static getDerivedStateFromProps(nextProps, prevState) {
		// 通过接受父组件props判断是否执行更新,返回null不更新
        console.log("getDerivedStateFromProps");
    }

    // 最近一次渲染输出(提交到 DOM 节点)之前调用
    getSnapshotBeforeUpdate(prevProps, prevState) {
		// 判断dom节点更新阶段更新时,及时获取更新后的dom节点
        console.log("getSnapshotBeforeUpdate");
    }

    // 在后代组件抛出错误后被调用
    static getDerivedStateFromError(error) {
        console.log("getDerivedStateFromError");
    }

    // 在后代组件抛出错误后被调用
    componentDidCatch(error, info) {
        console.log("componentDidCatch");
    }
}

export default Cycle;

在实际开发中,比较常用的生命周期方法有:
render(), constructor(), componentDidMount(), componentDidUpdate, componentWillUnmount();
不常用的生命周期方法有:shouldComponentUpdate(), static getDerivedStateFromProps(), getSnapshotBeforeUpdate(), static getDerivedStateFromError(), componentDidCatch();
还有一些过时的就不列举了,过时的在开发以不推荐使用,后续版本会淘汰掉,能不用就不要用;

hooks 组件的钩子函数

import React from 'react';

const Hooks = (props) => {
    // useState 与类组件的state类似
    const [name, setName] = React.useState("name");

    // React.useMemo 组件Dom节点,进行计算一些包括要渲染的Dom或者数据,根据依赖参数进行更新
    React.useMemo(() => {
        console.log("组件DOM节点没有渲染之前调用一次");
    }, []);

    const renderDom = React.useMemo(() => {
        return () => {
            console.log("组件DOM节点没有渲染之前根据依赖参数props调用");
        }
    }, [props]);

    // React.useEffect hooks的组件生命周期其实就是钩子函数useEffect的不同用法,
    // 传递参数的不同会导致不同的结果
    React.useEffect(() => {
        console.log("组件初始化调用一次");
    }, []);

    React.useEffect(() => {
        console.log("组件根据依赖参数props更新调用");
    }, [props]);

    React.useEffect(() => {
        return () => {
            console.log("组件卸载调用");
        }
    }, []);

    //  React.useCallback 一个钩子函数,通过包裹我们的普通函数进行性能优化
    const handleClick = React.useCallback(() => {
        console.log("监听事件通过钩子函数包裹,优化性能");
    }, []);

    // 返回 DOM节点
    return <div>hooks</div>;
}

export default Hooks;
posted @ 2022-03-29 09:12  太轻描淡写了  阅读(107)  评论(0编辑  收藏  举报