zoukankan      html  css  js  c++  java
  • react 组件的生命周期

    前言

      在开发模式下,你可能会发现在组件第一次初始话的时候或者时更新的时候,对应的生命周期会出现运行两次的情况,这是因为在开发模式下,react使用了<React.StrictMode>组件,你可以直接在根目录下的index.tsx中注释掉他

    生命周期图鉴

      

    生命周期列表

      constructor(props):

        介绍:构造函数,组件加载时最先执行的生命周期钩子函数

        执行时机:组件首次渲染时会执行

        接收参数:props 由父级传递的props

      static getDerivedStateFromProps(props,state)

        介绍:当组件的state和props改变时执行的方法

        执行时机:组件首次渲染以及组件更新时执行

        接收参数:props 组件接收到的props,组件当前state

        返回值:必须要有返回值,且返回值必须为null 或 {}对象,返回为null的时候,视图会按照原有的props和state渲染,但返回值为{}的时候,会将其与state合并,并将最新的state作为本次视图渲染的依据

      shouldComponentUpdate(nextProps,nextState)

        介绍:组件即将更新之前执行的方法,可以通过return值决定组件是否更新渲染,但是即便组件没有更新渲染,state和props的改动还是存在,只是没有视图更新;这块可以用来做性能优化的东西

        执行时机:组件更新时执行

        接收参数:nextProps 组件接收的Props,nextState 组件当前的state

        返回值:返回一个boolean类型的值,如果是false,则组件更新到此为止,后续的渲染逻辑将不会执行

      render

        介绍:组件渲染函数,这是组件中唯一要实现的方法

        执行时机:组件首次渲染和组件更新时会触发

        接收参数:无

        返回值:返回一个元素作为渲染模板

      componentDidMount

        介绍:组件第一次挂载时执行生命周期钩子函数

        执行时机:组件首次渲染时执行

        接收参数:无

      getSnapshotBeforeUpdate(prevProps,prevState)

        介绍:组件渲染更新提交到真实dom之前生命周期钩子函数;在此处,已经可以访问更新后的ref,但是更新后的渲染结果仍未提交到真实dom,真实dom仍然是旧的。

        执行时机:组件更新时执行

        接收参数:组件此时的props和state

        返回值:在此方法内返回的任何值,都会被componentDidUodate接收

      componentDidUpdate(prevProps,prevState,snapshot)

        介绍:组件更新后生命周期钩子函数;

        执行时机:组件更新完成后执行

        接收参数:prevProps为组件props、prevState为组件state、snapshot为组件getSnapshotBeforeUpdate中return的值

      componentWillUnmount

        介绍:销毁前调用,在这个时候组件的一切功能都是可以正常使用的,但是在此调用setState,组件永远不会更新,因为在此此方法执行之后,组件将进行销毁

        执行时机:组件销毁前调用

        接收参数:无

    过时的生命周期方法 这些声明周期虽然仍然有效,但是不推荐使用

    UNSAFE_componentWillMount()

    UNSAFE_componentWillReceiveProps()

    UNSAFE_componentWillUpdate()

    详细信息

    constructor

      构造函数react 实例话第一步就是执行这个方法,在这里你可以定义state的初始数据。这个方法可以不定义,但是如果你定义之后,就必须在内部使用super()方法,这是es6的规范

      

    render

      这个钩子函数虽然是组件的渲染方法,但并不是真正意义上的把元素渲染成dom的方法,在它之后还有一个把元素渲染成dom的步骤,这一步只是return一个元素对象,这个并不是组件的执行渲染功能的函数,

      它的返回值是一个这样的react 元素对象,react就是最终通过它去生成dom对象。它是唯一一个react.Componet 类中必须实现的方法

    componentDidMount 

      组件渲染完成并且挂载在dom上之后调用,这个类似与vue的mounted,者意味着这一步组件中的元素都已经转话成真实的dom,我们可以在这里进行dom操作

      它可以访问this

      并且不携带参数

      e的值为undefined

      

    shouldComponentUpdate

      组件即将更新时触发,这个生命周期钩子在getDerivedStateFromProps之后,在render之前调用,通过return false或者true 来决定是否更新组件。

      这个组件在提升性能方面非常有用,假设一个父组件中存在10个子组件,那么当父组件state或者props改变时,即便子组件没有变更,也会重新渲染,这样白白浪费了渲染开销,所以可以在子组件中的sholdComponentUpdate中判断state或者props是否发生改变,然后决定子组件是否重新渲染

      这个方法接受两个参数nextProps 更新后的props nextState 更新后的state

     getSnapshotBeforeUpdate

      当元素最近一次渲染输出(既是当数据更新,触发react重新渲染组件之后,在把新渲染的组件挂载在dom之前)触发,这个钩子函数你应该极少使用。

     getSnapshotBeforeUpdate(prevProps, prevState) {
            //这个方法必须要和componentDidUpdate方法一起使用
            console.log(this);//可以访问this
            // 不推荐在此处使用setState,虽然仍可以使用
            return {a: 415463564}; //在这里return的值,会传递给componentDidUpdate钩子函数的第三个参数
        }

    componentDidUpdate

    componentDidUpdate(prevProps, prevState, snapshot) {
            console.log(prevProps);//更新之前的props
            console.log(prevState);//更新之前的state
            console.log(snapshot);//getSnapshotBeforeUpdate生命周期中return的值
            console.log(this.state);//这里仍然可以获取this
            //值得一提的是在这里尽量不要掉用setState(),不然有可能会造成无限更新的情况发生
            //因为在这一步react已经完成更新了,所以不能像shouComponentUpdate一下修改prevProps或者是prevState来触发视图更新
        }

    static getDerivedStateFromProps()

      在第一次进入,和发生更新的时候(setState,props更新或者调用forceUpdate)都会触发这个生命周期钩子,并且是在render方法之前调用。同时通过return值,我们可以改变最后的渲染结果。(return的值会直接同步至state中,比如在state中有一个index属性,它的值为1,而你在此方法内返回{index:99},那么最后渲染的值为99,但是不建议在这里直接改变state,我们应当遵循react的setState改变原则)。ps:在这里无法访问this

    static getDerivedStateFromProps(props, state) {
            console.log(props, state);
            state.idx = 180; //只要在此方法内改变props 或者state中的值,那么最终的渲染结果,就以此为准。即便return 为null
            return null;
        }

    一些api

    setState 

      setState是发起一个更新组件的请求,而非立即更新,它不会立即改变state和立即更新组件。为了提高更新效率,react不会对每一次的改变立即更新,而是形成一个更新队列,批量更新。这样就避免了很多无用的更新。

      不要再组件更新的钩子函数中使用setState(),因为即便state没有发生任何变化,此方法也会促使视图进行更新。所以不要在会重复触发的,组件更新生命周期钩子函数中:shouldComponentUpdate、render、getSnapshotBeforeUpdate、componentWillUpdate使用此方法,有可能会造成无限次数的数据更新

    componentDidMount() {
            for (let i = 0; i < 100; i++) {
                this.setState({idx: i++});
            } //最终只会触发一次componentDidUpdate
         console.log(this.state.idx) //打印结果为state在constructor 定义初始值 1
    }

      setState可接收不同的参数 

      1.接收一个回调函数

     this.setState((state, props) => {
                //state和props 参数是目前组件的的最新的state,props。但是它仍不是此回调函数 return之后的state值
                
                return {idx: '12345'} //return的值会与state进行浅合并,只有在return语句执行之后,组件的state才会进行更新
            })

      2.接收一个对象和一个回调函数,如果你想立即获取改变后的state值,可以使用这个方法

     //通过第一个参数对象修改state,第二个回调函数参数会在componentDidUpdate之后执行
            this.setState({idx: e}, function () {
                console.log(this.state);
            })

    forceUpdate 强制组件重新更新

     this.state.idx=999;
            //强制组件重新渲染,回调函数将在componentDidUpdate之后执行
            this.forceUpdate(function () {
                console.log('强制执行')//
            })

    结合react的生命周期图示,你可能会更清晰

  • 相关阅读:
    docker学习笔记3:镜像操作(查找和下载)
    docker学习笔记2:容器操作
    docker学习笔记1:docke环境的查看
    CSS鼠标样式
    Ubuntu下安装和配置mysql
    HR函数学习01——创建组织单位
    SAP模块常用增强总结{转载}
    SAP物料批次管理配置及操作手册(轉載)
    交货单开票
    ABAP之PINYING拼音
  • 原文地址:https://www.cnblogs.com/wrhbk/p/12930616.html
Copyright © 2011-2022 走看看