react 生命周期钩子详解(1)

react 生命周期钩子详解(1)

本文章使用react环境版本为17.0.1,文章中出现的 (已废弃)等标识皆对react 17+版本而言

React中组件也有生命周期,也就是说也有很多钩子函数供我们使用

1、早期的react生命周期钩子

根据下图我们可以将react的生命周期钩子分为四个阶段:初始化、挂载阶段、更新阶段,销毁阶段
在这里插入图片描述

(1)初始化

初始化时期的生命周期钩子是constructor

只要这个组件被实例化,被挂载的时候,这个钩子就会被优先调用,他有一个参数 pros 可以调用 super(props) ,用来将父组件传来的 pros 绑定到这个类中,作用是状态初始化和属性读取,这个钩子只会在初始化时被调用一次。
constructor 中应当做些初始化的动作,如:初始化 state ,将事件处理函数绑定到类实例上,但也不要使用 setState() 。如果没有必要初始化 state 或绑定方法,则不需要构造 constructor ,或者把这个组件换成纯函数写法。

当然也可以利用 props 初始化 state ,在之后修改 state 不会对 props 造成任何修改,但仍然建议大家提升状态到父组件中,或使用 redux 统一进行状态管理。

import React, { Component } from 'react'

export default class App extends Component {
    //初始化期钩子,只要这个组件被实例化被挂载的时候,这个钩子就会被优先调用
    //参数props
    //作用:状态初始化和属性读取
    constructor(pros){
        //调用super把props递到父组件上去
        super(pros)
        // 在状态初始化时读取了从父组件上传来的props
        this.state={
            title:pros.title
        }
        console.log("constructor")
    }
    //我们这里用 componentDidMount 钩子来验证 constructor 这个钩子只会被调用一次
    componentDidMount(){
    	// 在这里修改数据 constructor 钩子也不会被再次调用
        this.setState({
            title:"hello"
        })
        console.log("componentDidMount")
    }
    render() {
        return (
            <div>
                你好
            </div>
        )
    }
}

打印结果:
在这里插入图片描述

(2)挂载阶段

本阶段有3个生命周期钩子分别是 componentWillMount(已废弃) 、render 、componentDidMount

1)componentWillMount ( UNSAFE_componentWillMount )

这个钩子是在进入挂载阶段时期第一个运行,在 react 17.x版本之后已废弃
在组件挂载前被调用,在这个方法中调用 setState() 不会起作用,是由于他在 render() 前被调用。
这个方法因为是在渲染之前被调用,也是惟一一个可以直接同步修改 state 的地方。

import React, { Component } from 'react'

export default class App extends Component {
    constructor(){
    	super()
        console.log("constructor")
    }

    componentWillMount(){
        console.log("componentWillMount")
    }

    componentDidMount(){
        console.log("componentDidMount")
    }
    
    render() {
    	console.log("render")
        return (
            <div>
                你好
            </div>
        )
    }
}

使用时会如下图所示
在这里插入图片描述

并提示我们可以使用 UNSAFE_componentWillMount 代替,用来消除黄色的警告信息,而在react 18.x的版本中将会将所有弃用的生命周期重命名为它们的新名称

import React, { Component } from 'react'

export default class App extends Component {
    constructor(){
        super()
        console.log("constructor")
    }
    
    UNSAFE_componentWillMount(){
        console.log("UNSAFE_componentWillReceiveProps")
    }

    componentDidMount(){
        console.log("componentDidMount")
    }

    render() {
    	console.log("render")
        return (
            <div>
                你好
            </div>
        )
    }
}

在这里插入图片描述
在这个钩子中可以拿到 this ,也能够利用 setState() 更改 state 状态,不过尽量不要在此进行 state 状态的更改,可能会引起一些以外的错误,尽量在 constoructor中直接设置好,在这个钩子中更改state状态不会两次调用 render,因为他是在 render 之前就将 state 更改了。它与 constoructor 一样,如果在后面更改 state 状态,他不会再次被调用,只会被调用一次

UNSAFE_componentWillMount(){
        console.log(this)
        console.log("UNSAFE_componentWillReceiveProps")
    }

在这里插入图片描述

2)render

render()方法是必需的。当他被调用时,他将计算this.propsthis.state,并返回以下一种类型:

  • React元素。通过jsx创建,既可以是dom元素,也可以是用户自定义的组件。
  • 字符串或数字。他们将会以文本节点形式渲染到dom中。
  • Portals。react 16版本中提出的新的解决方案,可以使组件脱离父组件层级直接挂载在DOM树的任何位置。
  • null,什么也不渲染
  • 布尔值。也是什么都不渲染。

当返回null,false,ReactDOM.findDOMNode(this)将会返回null,什么都不会渲染。

render()方法必须是一个纯函数,他不应该改变state,也不能直接和浏览器进行交互,应该将事件放在其他生命周期函数中。
如果shouldComponentUpdate()返回falserender()不会被调用。

3)componentDidMount

在组件被装配后立即调用。初始化使得DOM节点应该进行到这里。

通常在这里进行ajax请求

如果要初始化第三方的dom库,也在这里进行初始化。只有到这里才能获取到真实的dom.

如果我们在这个函数中更改 state 状态,会在此执行 render 函数

import React, { Component } from 'react'

export default class App extends Component {
    constructor(){
        super()
        console.log("constructor")
    }

    // componentWillMount(){
    //     console.log("componentWillMount")
    // }

    UNSAFE_componentWillMount(){
        console.log(this)
        console.log("UNSAFE_componentWillReceiveProps")
    }

    componentDidMount(){
        console.log("componentDidMount")
        this.setState({
            title:"hello"
        })
    }

    render() {
        console.log("render")
        return (
            <div>
                你好
            </div>
        )
    }
}

在这里插入图片描述
第一次 render 是在组件挂载是被调用,第二次被调用是在更改 state 状态之后

(3)更新阶段

更新阶段分为对 pros 的更新和对 state 的更新,他们之间的区别仅仅是 pros 更新多了一个 componentWillReceiveProps 钩子

1) componentWillReceiveProps(UNSAFE_componentWillReceiveProps(nextProps))

它与之前的 componentWillMount 一样被废弃,可以使用UNSAFE_componentWillReceiveProps(nextProps)

当组件挂载后,接收到新的props后会被调用。如果需要更新state来响应props的更改,则可以进行this.propsnextProps的比较,并在此方法中使用this.setState()

如果父组件会让这个组件重新渲染,即使props没有改变,也会调用这个方法。

React不会在组件初始化props时调用这个方法。调用this.setState也不会触发。

2) shouldComponentUpdate(nextProps, nextState)

调用shouldComponentUpdate使React知道,组件的输出是否受stateprops的影响。默认每个状态的更改都会重新渲染,大多数情况下应该保持这个默认行为。

在渲染新的propsstate前,shouldComponentUpdate会被调用。默认为true。这个方法不会在初始化时被调用,也不会在forceUpdate()时被调用。返回false不会阻止子组件在state更改时重新渲染。

如果shouldComponentUpdate()返回falsecomponentWillUpdate,rendercomponentDidUpdate不会被调用。

官方并不建议在shouldComponentUpdate()中进行深度查询或使用JSON.stringify(),他效率非常低,并且损伤性能。

3)componentWillUpdate(UNSAFE_componentWillUpdate(nextProps, nextState)))

它与之前的 componentWillMount 一样被废弃,可以使用UNSAFE_componentWillUpdate(nextProps, nextState)

在渲染新的stateprops时,UNSAFE_componentWillUpdate会被调用,将此作为在更新发生之前进行准备的机会。这个方法不会在初始化时被调用。

不能在这里使用this.setState(),也不能做会触发视图更新的操作。如果需要更新stateprops,调用getDerivedStateFromProps

4)render

见上述

5)componentDidUpdate(prevProps, prevState, snapshot)

在更新发生后立即调用componentDidUpdate()。此方法不用于初始渲染。当组件更新时,将此作为一个机会来操作DOM。只要您将当前的props与以前的props进行比较(例如,如果props没有改变,则可能不需要网络请求),这也是做网络请求的好地方。

如果组件实现getSnapshotBeforeUpdate()生命周期,则它返回的值将作为第三个“快照”参数传递给componentDidUpdate()。否则,这个参数是undefined

(4) 卸载阶段
componentWillUnmount()

在组件被卸载并销毁之前立即被调用。在此方法中执行任何必要的清理,例如使定时器无效,取消网络请求或清理在componentDidMount中创建的任何监听。

react 16.3及16.4中生命周期钩子做出了重大改变

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
React生命周期流程图可以分为两个版本:旧版和新版。 旧版生命周期流程图包括以下阶段: - 实例化阶段:getDefaultProps -> getInitialState -> componentWillMount -> render -> componentDidMount - 更新阶段:componentWillReceiveProps -> shouldComponentUpdate -> componentWillUpdate -> render -> componentDidUpdate - 卸载阶段:componentWillUnmount 新版生命周期流程图如下: - 实例化阶段:constructor -> static getDerivedStateFromProps -> render -> componentDidMount - 更新阶段:static getDerivedStateFromProps -> shouldComponentUpdate -> render -> getSnapshotBeforeUpdate -> componentDidUpdate - 卸载阶段:componentWillUnmount 这些生命周期钩子函数提供了不同的时机,让我们可以在组件的不同状态下执行特定的操作。通过实现这些钩子函数,我们可以控制组件的渲染、更新和卸载等过程。请注意,在React 17及更高版本中,一些生命周期钩子函数已被标记为过时,建议使用新的生命周期钩子函数来替代。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [【React】第六部分 生命周期](https://blog.csdn.net/Trees__/article/details/126190516)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 33.333333333333336%"] - *2* [React组件生命周期详解](https://download.csdn.net/download/weixin_38553648/13327682)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 33.333333333333336%"] - *3* [React学习笔记【6】(React生命周期)](https://blog.csdn.net/weixin_50378623/article/details/130507852)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 33.333333333333336%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值