React 组件生命周期

React生命周期,就是指组件从被创建出来,到被使用,最后被销毁的这么一个过程。而在这个过程中,React提供了我们会自动执行的不同的钩子函数,我们称之为生命周期函数。

一、类式组件

React的生命周期可以分为三个阶段:挂载渲染卸载

1.  Mounting(挂载阶段)------ 创建构造函数并初始化,让我们在页面加载完成前后做一些事情。

  • constructor(构造函数在类组件中比较常见)
  • getDerivedStateFromProps
  • render(render函数)只能访问this.props和this.state,不允许修改状态和DOM输出
  • componentDidMount(组件挂载)------ 一般在这个钩子中做一些初始化的工作,比如:开启定时器,发送网络请求,订阅消息


2. Updating(更新阶段)——状态更新引起的变化,更新页面UI显示或数据更改。

  • getDerivedStateFromProps
  • shouldComponentUpdate
  • render(render函数)------ 渲染组件的UI
  • getSnapshotBeforeUpdate
  • componentDidUpdate(组件更新)------ 可以修改DOM

3. Unmounting(卸载阶段)------ 销毁一个组件,销毁前暴露出一个事件,让我们可以在组件销毁前做一些逻辑的处理。

  • componentWillUnmount(组件销毁)  ------ 一般在这个钩子中做一些收尾的工作,比如:关闭定时器,取消订阅消息
     

代码示例:

import React from 'react'
import ReactDOM from 'react-dom'
 
class App extends React.Component {
    // constructor用来初始化组件属性,this.state定义数据,super()为了接收到父类的this指针
    // 创建构造函数
    constructor(props) {
        super(props);
        this.state = {
            data: 'Old State'
        }
        console.log('初始化数据', constructor)
    }
    // 组件将要加载,整个组件还没有加载出来,js逻辑已经可以执行, 异步方法可以放在这里执行
    componentWillMount() {
        console.log('componentWillMount')
    }
    // 组件加载完成
    componentDidMount() {
        console.log('componentDidMount')
    }
    // 接收父组件传递过来的参数props时触发
    componentWillReceiveProps() {
        console.log('componentWillReceiveProps')
    }
    // 判断组件是否需要更新,它需要一个返回值,默认为true
    shouldComponentUpdate() {
        console.log('shouldComponentUpdate')
        return true; // 需要一个布尔返回值, 比如true或false来判断组件是否要根据值的变化而更新,
    }
    // 组件将要更新, 如果shouldComponentUpdate的返回值为true,那这个函数就要为组件更新做准备了
    // 如果shouldComponentUpdate返回值为false,则组件不会更新,componentWillUpdate,componentDidUpdate都不会执行
    componentWillUpdate() {
        console.log('componentWillUpdate')
    }
    // 组件更新完成
    componentDidUpdate() {
        console.log('componentDidUpdate')
    }
    // 处理点击事件
    handleClick() {
        console.log('更新数据')
        this.setState({
            data: 'New State'
        })
    }
    // 把组件渲染到页面上
    render() {
        console.log('render')
        return (
            <div>
                <h1>Props:{this.state.data}</h1>
                <button onClick={() => this.handleClick()}>更新数据</button>
            </div>
        )
    }
}
 
ReactDOM.render(
    <div>
        <App />
    </div>,
    document.getElementById('app')
)

父子组件初始化
父子组件第一次进行渲染加载时控制台的打印顺序为:

Parent 组件: constructor()
Parent 组件: getDerivedStateFromProps()
Parent 组件: render()
Child 组件:   constructor()
Child 组件:   getDerivedStateFromProps()
Child 组件:   render()
Child 组件:   componentDidMount()
Parent 组件: componentDidMount()
 

父子组件生命周期执行顺序总结
当子组件自身状态改变时,不会对父组件产生副作用的情况下,父组件不会进行更新,即不会触发父组件的生命周期

当父组件中状态发生变化(包括子组件的挂载以及卸载)时,会触发自身对应的生命周期以及子组件的更新

render 以及 render 之前的生命周期,则 父组件先执行
render 以及 render之后的声明周期,则子组件先执行,并且是与父组件交替执行
当子组件进行卸载时,只会执行自身的 componentWillUnmount 生命周期,不会再触发别的生命周期
 

即将废弃的钩子

  • componentWillMount
  • componentWillReceiveProps
  • componentWillUpdate

现在使用会出现警告,下一个大版本需要加上UNSAFE_前缀才能使用,以后可能会被彻底废弃,不建议使用。

  • componentWillMount: 被 UNSAFE_componentWillMount 取代。
  • componentWillReceiveProps: 被 UNSAFE_componentWillReceiveProps 取代。
  • componentWillUpdate: 被 UNSAFE_componentWillUpdate 取代。

这些带有 UNSAFE_ 前缀的函数是 React 在新版本中标记为不安全的生命周期函数,提醒开发者在新代码中避免使用它们。React 团队计划在未来版本中完全移除这些不安全的生命周期函数。
 

二、函数式组件

       在 React 之前的版本中,函数式组件确实没有类组件那样的生命周期方法。这是因为函数式组件最初被设计为纯粹的“无状态”组件,用于简单的 UI 呈现。在这种情况下,组件不需要进行复杂的生命周期管理,因此没有提供生命周期方法。

在 React 中,函数式组件在 React 16.8 版本引入的 Hooks 之后,可以使用 Hooks 来模拟类组件中的生命周期功能。主要用到的是 useEffect 这个 Hook。以下是函数式组件生命周期相关的一些常见钩子:

useEffect

  • useEffect 可以在函数式组件中执行副作用操作,类似于类组件中的 componentDidMountcomponentDidUpdatecomponentWillUnmount 三个生命周期函数的组合。
import React, { useEffect } from 'react'

function MyFunctionalComponent() {
  useEffect(() => {
    // 在组件挂载后执行,相当于 componentDidMount
    console.log('组件挂载了')

    // 在组件更新后执行,相当于 componentDidUpdate
    console.log('组件更新了')

    return () => {
      console.log('组件即将卸载')
      // 在组件卸载前执行,相当于 componentWillUnmount
    }
  }, [/* dependencies */]) // 可选的依赖数组,当数组中的依赖发生变化时,effect 就会重新执行
}

useLayoutEffect

  • useLayoutEffectuseEffect 类似,但在所有 DOM 变更后同步触发,可以用于获取 DOM 元素的布局信息
import React, { useLayoutEffect } from 'react'

function MyFunctionalComponent() {
  useLayoutEffect(() => {
    // 在所有 DOM 变更后同步执行
  }, [/* dependencies */])
}

useMemo 和 useCallback

  • useMemouseCallback 可以用于性能优化,避免在每次渲染时都重新计算某个值或创建某个函数。
import React, { useMemo, useCallback } from 'react'

function MyFunctionalComponent({ data }) {
  const memoizedValue = useMemo(() => computeExpensiveValue(data), [data])

  const memoizedCallback = useCallback(() => {
    doSomethingWith(memoizedValue)
  }, [memoizedValue])

  // 其他组件逻辑
}

三、什么是React副作用

在 React 中,副作用指的是与组件渲染结果无关的任何操作,例如:

  • 发送网络请求
  • 修改 DOM 元素
  • 访问本地存储
  • 订阅或取消订阅事件
  • 改变组件状态外的变量等

这些操作会影响组件的行为和状态,但是并不会直接影响渲染结果。在 React 中,应该将副作用分离出来,以便更好地控制组件的行为和状态。

通常,React 使用钩子函数(如 useEffect)来处理副作用。在 useEffect 中,可以执行一些副作用操作,例如发送网络请求或订阅事件,以及在组件卸载时清除这些操作。这可以保持组件的一致性和可维护性。

  • 22
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
引用\[1\]:当渲染过程,生命周期或子组件的构造函数中抛出错误时,会调用如下方法: static getDerivedStateFromProps()componentDidCatch() 常用生命周期 1.render() 。 引用\[2\]:当组件实例被创建并插入DOM时,其生命周期调用顺序如下: constructor()static getDerivedStateFromProps()render()componentDidMount() 组件更新时 。 引用\[3\]:组件渲染之后调用,只调用一次 2.4、生命周期函数代码示例 import React, { Component } from 'react' export default class OldReactComponent extends Component { constructor(props) { super(props) // getDefaultProps:接收初始props // getInitialState:初始化state } state = { } componentWillMount() { // 组件挂载前触发 } render() { return ( <h2>Old React.Component</h2> ) } componentDidMount() { // 组件挂载后触发 } componentWillReceivePorps(nextProps) { // 接收到新的props时触发 } shouldComponentUpdate(nextProps, nextState) { // 组件Props或者state改变时触发,true:更新,false:不更新 return true } componentWillUpdate(nextProps, nextState) { // 组件更新前触发 } componentDidUpdate() { // 组件更新后触发 } componentWillUnmount() { // 组件卸载时触发 } } 3、新的生命周期 3.1、Mounting(加载阶段:涉及4个钩子函数) 。 问题:react函数组件 生命周期 回答: React函数组件生命周期相对简单,只有两个阶段:Mounting(加载阶段)和Unmounting(卸载阶段)。在Mounting阶段,函数组件会依次执行以下生命周期函数:constructor()、render()和componentDidMount()。constructor()函数用于初始化组件的状态和绑定事件处理函数。render()函数用于渲染组件的UI。componentDidMount()函数在组件被插入DOM后调用,可以进行一些异步操作或订阅事件。在Unmounting阶段,函数组件会执行componentWillUnmount()函数,在组件被卸载前进行一些清理工作,比如取消订阅事件或清除定时器。除了这些生命周期函数,函数组件没有其他生命周期函数可用。 #### 引用[.reference_title] - *1* *2* [React生命周期详解](https://blog.csdn.net/weixin_46872121/article/details/126623679)[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^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] - *3* [关于React组件生命周期函数的详解](https://blog.csdn.net/p445098355/article/details/104667187)[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^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值