IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> JavaScript知识库 -> React:新旧生命周期及其对比 -> 正文阅读

[JavaScript知识库]React:新旧生命周期及其对比

概述

不管是vue还是React,它都有一个生命周期,它描述了组件从创建到销毁的整个生命过程,其中含有有很多的钩子函数连接而成。这里主要讲React新旧生命周期,以及他们的对比


生命周期(旧)

周期图如下
在这里插入图片描述

其中左边是挂载时,右边是更新时,下边是更新时

挂载时

可以看出挂载时的更新数据顺序依次如下
1)constructor:构造器
2)componentWillMount:组件将要挂载
3)render:渲染
4)componentDidMount:组件挂载完成

可以通过代码来进行验证

  class Life extends React.Component{
            // 构造器
            constructor(props){
                super(props)
                console.log("constructor");
            }
            // 组件将要挂载的钩子
            componentWillMount(){
                console.log("componentWillMount");
            }
            // 渲染
            render(){
                console.log("render");
                return(
                    <div>
                        <button onClick={this.remove}>卸载组件</button>
                    </div>
                )
            }
            // 组件挂载完毕的钩子
            componentDidMount(){
                console.log("componentDidMount");
            }
            // 组件将要卸载的钩子
            componentWillUnmount(){
                console.log("componentWillUnmount");
            }
            remove=()=>{
                ReactDOM.unmountComponentAtNode(document.getElementById("root"))
            }
        }
        ReactDOM.render(<Life/>,document.getElementById("root"))

打印结果如图
在这里插入图片描述
当然这并不和函数声明顺序有关,这里不更改顺序做演示。

更新时

在这里插入图片描述
由图可知更新时一共有三条可走的线路,分别是父组件render、setState、forceUpdate

父组件render

如图中红线所示
就是指父组件引用了子组件时,子组件更新数据的生命周期。
可以看到它的生命周期如下

1)componentWillReceiveProps:组件将要接收属性
2)shouldComponentUpdate:组件是否应该更新
3)componentWillUpdate:组件将要更新
4)componentDidUpdate:组件完成更新
注意:
这里shouldComponentUpdate相当于一个阀门,其返回值是一个布尔值,决定了是否继续后面的执行,其默认值为true

这里举一个例子:
需求:
父组件Father引用子组件Son,并将父组件state里的movie属性传给子组件,子组件通过props引用movie属性,然后通过点击父组件内的changeMovie更改movie属性状态,从而观察子组件更新时生命周期
在这里插入图片描述

代码:

 class Father extends React.Component{
        state={
            movie:"哥斯拉大战金刚"
        }
        changeMovie=()=>{
        this.setState({
            movie:this.state.movie==="哥斯拉大战金刚"?"复仇者联盟":"哥斯拉大战金刚"
        })
        }
        render(){
            const {movie}=this.state
            return (
                <div>
                    <Son movie={movie}/>
                    <button onClick={this.changeMovie}>切换电影</button>
                </div>
            )
        }

    }
    class Son extends React.Component{
        //组件将要接收属性
        componentWillReceiveProps(){
            console.log("componentWillReceiveProps");
        }
        //组件是否应该更新
        shouldComponentUpdate(){
            console.log("shouldComponentUpdate");
            return true
        }
        // 组件将要更新
        componentWillUpdate(){
            console.log("componentWillUpdate");
        }
        render(){
            console.log("render");
            const {movie}=this.props
            return(
                <div>
                    电影:{movie}
                </div>
            )
        }
        
            //组件更新完成
            componentDidUpdate(){
                console.log("componentDidUpdate");
            }
    }

    ReactDOM.render(<Father/>,document.getElementById("root"))

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

setState

在这里插入图片描述
如图中黄线所示
通过setState来更新数据是最常见的
1)shouldComponentUpdate:组件是否应该更新
2)componentWillUpdate:组件将要更新
3)componentDidUpdate:组件完成更新

通过一个简单的计数器演示
当数据改变,调用setState后打印更新周期
在这里插入图片描述
代码:

 class Life extends React.Component{
            state={
                count:0
            }
            add=()=>{
                this.setState({
                    count:this.state.count+1
                })
            }
            //组件是否应该更新
            shouldComponentUpdate(){
                console.log("shouldComponentUpdate");
                return true
            }
            //组件将要更新
            componentWillUpdate(){
                console.log("compontWillUpdate");
            }
            //渲染
            render(){
                console.log("render");
                const {count}=this.state
                return (
                    <div>
                        <h2>计数:{count}</h2>
                        <button onClick={this.add}>加一</button>
                    </div>
                )
            }
            //组件更新完成
            componentDidUpdate(){
                console.log("componentDidUpdate");
            }
        }
        ReactDOM.render(<Life/>,document.getElementById("root"))

forceUpdate

在这里插入图片描述如绿线所示
forceUpdate,顾名思义,强制更新。从图中也可以看出,其跳过了阀门,直接进行更新了
还是以计数器为例,不过增加了一个强制更新
在这里插入图片描述
可以看到这里给阀门关闭后,加一只输出shouldComponent,而强制加一后发生更新

   class Life extends React.Component{
            state={
                count:0
            }
            add=()=>{
                this.setState({
                    count:this.state.count+1
                })
            }
            force=()=>{
                this.setState({
                    count:this.state.count+1
                })
                this.forceUpdate()
            }
            //组件是否应该更新
            shouldComponentUpdate(){
                console.log("shouldComponentUpdate");
                return false
            }
            //组件将要更新
            componentWillUpdate(){
                console.log("compontWillUpdate");
            }
            //渲染
            render(){
                console.log("render");
                const {count}=this.state
                return (
                    <div>
                        <h2>计数:{count}</h2>
                        <button onClick={this.add}>加一</button>
                        <button onClick={this.force}>强制加一</button>
                    </div>
                )
            }
            //组件更新完成
            componentDidUpdate(){
                console.log("componentDidUpdate");
            }
        }
        ReactDOM.render(<Life/>,document.getElementById("root"))

卸载时

componentWillUnmount:组件将要卸载时
组件卸载前调用的钩子函数,可以通过调用ReactDOM.unmountComponentAtNode函数检验


生命周期(新)

在这里插入图片描述
可以看到新的生命周期如上
由于例子差不多,不做演示

挂载时

1)constructor:构造器
2)getDerivedStateFromProps:从属性中得到派生的状态
3)render:渲染
4)componentDidMount:组件完成挂载

更新时

1)getDerivedStateFromProps:从属性中得到派生的状态
2)getSnapshotBeforeUpdate:更新前得到快照
3)componentDidUpdate:组件完成更新

卸载时

componentWillUnmount:组件将要卸载时


新旧生命周期的对比

1)可以看出,新生命周期中去掉了三个will钩子函数,分别是componentWillMount、componentWillUpdate、componentWillReceiveProps

原因查官方文档可知:这些生命周期方法经常被误解和滥用;此外,我们预计,在异步渲染中,它们潜在的误用问题可能更大。我们将在即将发布的版本中为这些生命周期添加 “UNSAFE_” 前缀。(这里的 “unsafe” 不是指安全性,而是表示使用这些生命周期的代码在 React 的未来版本中更有可能出现 bug,尤其是在启用异步渲染之后。)

2)新生命周期中新增getDerivedStateFromProps、getSnapshotBeforeUpdate
新的静态 getDerivedStateFromProps 生命周期方法在组件实例化之后以及重新渲染之前调用。它可以返回一个对象来更新 state,或者返回 null 来表示新的 props 不需要任何 state 的更新。

新的 getSnapshotBeforeUpdate 生命周期方法在更新之前(如:更新 DOM 之前)被调用。此生命周期的返回值将作为第三个参数传递给 componentDidUpdate。(通常不需要,但在重新渲染过程中手动保留滚动位置等情况下非常有用。)

  JavaScript知识库 最新文章
ES6的相关知识点
react 函数式组件 & react其他一些总结
Vue基础超详细
前端JS也可以连点成线(Vue中运用 AntVG6)
Vue事件处理的基本使用
Vue后台项目的记录 (一)
前后端分离vue跨域,devServer配置proxy代理
TypeScript
初识vuex
vue项目安装包指令收集
上一篇文章      下一篇文章      查看所有文章
加:2021-07-10 14:27:32  更:2021-07-10 14:27:44 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/9 7:17:41-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码