当前位置: 首页 > news >正文

react组件的生命周期

组件是一个类,当它被使用的时候实例化,然后挂载到页面中。

1.组件第一次加载

组件第一次加载生命周期的执行顺序:

  • defaultProps
  • constructor
  • componentWillMount
  • render
  • componentDidMount
export default class Counter extends Component {
    //如果传递值了使用传递值,没有传值使用默认值:默认属性对象
    static defaultProps = {
        count: 0
    }
    constructor(props) {
        console.log('constructor');
        super(props);
        this.state = { count: props.count };//初始化默认状态对象
    }
    componentWillMount() {
        console.log('1.组件将要挂载 componentWillMount');
    }
    render() {
        console.log('2.render 挂载');
        return (
            <div>
                父计数器:{this.state.count}
            </div>
        )
    }
    //组件挂载完成
    componentDidMount() {
        console.log('3.componentDidMount 组件挂载完毕');
    }
}

复制代码

输出

constructor
1.组件将要挂载 componentWillMount
2.render 挂载
3.componentDidMount 组件挂载完毕
复制代码

2.修改状态

添加一个button按钮去修改计数器的state,查看状态更新后组件声明周期的流程

  • shouldComponentUpdate
  • componentWillUpdate
  • render
  • componentDidUpdate
export default class Counter extends Component {
    //如果传递值了使用传递值,没有传值使用默认值:默认属性对象
    static defaultProps = {
        count: 0
    }
    constructor(props) {
        console.log('constructor');
        super(props);
        this.state = { count: props.count };//初始化默认状态对象
    }
    componentWillMount() {
        console.log('1.组件将要挂载 componentWillMount');
    }
    
    //当需要旧状态时,使用传入一个方法,参数为旧状态这种形式
    handleClick = () => {
        this.setState(prevState => ({
            count: prevState.count + 1
        }));
    }
    
    //询问组件是否要被更新,当一个组件的属性或者状态只要有一个发生了改变 ,默认就会重新渲染。返回true则组件更新,返回false则组件不更新
    shouldComponentUpdate(nextProps, nextState) {
        if (nextState.count < 10) {
            return true;
        } else {
            return false;
        }
    }
    
    componentWillUpdate() {
        console.log('componentWillUpdate');
    }
    componentDidUpdate() {
        console.log('componentDidUpdate');
    }
    
    render() {
        console.log('2.render 挂载');
        return (
            <div>
                父计数器:{this.state.count}
                <button onClick={this.handleClick}>+</button>
            </div>
        )
    }
    //组件挂载完成
    componentDidMount() {
        console.log('3.componentDidMount 组件挂载完毕');
    }
}
复制代码

输出

constructor
1.组件将要挂载 componentWillMount
2.render 挂载
3.componentDidMount 组件挂载完毕
componentWillUpdate
2.render 挂载
componentDidUpdate
复制代码

3.接收新的属性

组件内属性不可以更改,只能通过父组件传递。

父组件:

export default class Counter extends Component {
    //如果传递值了使用传递值,没有传值使用默认值:默认属性对象
    static defaultProps = {
        count: 0
    }
    constructor(props) {
        console.log('constructor');
        super(props);
        this.state = { count: props.count };//初始化默认状态对象
    }
    componentWillMount() {
        console.log('1.组件将要挂载 componentWillMount');
    }
    handleClick = () => {
        this.setState(prevState => ({
            count: prevState.count + 1
        }));
    }
    //询问组件是否要被更新,当一个组件的属性或者状态只要有一个发生了改变 ,默认就会重新渲染
    shouldComponentUpdate(nextProps, nextState) {
        if (nextState.count < 10) {
            return true;
        } else {
            return false;
        }
    }
    componentWillUpdate() {
        console.log('componentWillUpdate');
    }
    componentDidUpdate() {
        console.log('componentDidUpdate');
    }
    render() {
        console.log('2.render 挂载');
        return (
            <div>
                父计数器:{this.state.count}
                <button onClick={this.handleClick}>+</button>
                //添加子组件 传递count属性
                <SubCounter count={this.state.count} />
            </div>
        )
    }
    //组件挂载完成
    componentDidMount() {
        console.log('3.componentDidMount 组件挂载完毕');
    }
}
复制代码

子组件

  • componentWillReceiveProps
  • shouldComponentUpdate
  • componentWillUpdate
  • componentDidUpdate
class SubCounter extends Component {
    //当子组件将要接收到父组件传给它的新属性的时候
    componentWillReceiveProps() {
        console.log('SubCounter componentWillReceiveProps');
    }
    shouldComponentUpdate(nextProps, nextState) {
        console.log('SubCounter shouldComponentUpdate');
        if (nextProps.count <= 5) {
            return true;
        } else {
            return false;
        }
    }
    componentWillUpdate() {
        console.log('SubCounter componentWillUpdate');
    }
    componentDidUpdate() {
        console.log('SubCounter componentDidUpdate');
    }
    render() {
        console.log('SubCounter render 挂载');
        return (
            <div>
                子计数:{this.props.count}
            </div>
        )
    }
}
复制代码

未点击加号输出:

constructor
1.组件将要挂载 componentWillMount
2.render 挂载
SubCounter render 挂载
3.componentDidMount 组件挂载完毕   //需要子组件加载完毕后父组件才会加载完毕

点击添加按钮 新增输出:
//先是父组件将要更新,然后渲染
componentWillUpdate
2.render 挂载
//子组件
SubCounter componentWillReceiveProps
SubCounter shouldComponentUpdate
SubCounter componentWillUpdate
SubCounter render 挂载
SubCounter componentDidUpdate
//父组件完成更新
componentDidUpdate
复制代码

4.组件的卸载

什么时候用到componentWillUnmount:

单页应用中,切换页面原组件需要销毁释放资源,如果原组件中有定时器等不能销毁时,需要在componentWillUnmount中清理资源占用,手动销毁定时器。

export default class Counter extends Component {
    //默认属性对象
    static defaultProps = {
        count: 0
    }
    constructor(props) {
        console.log('constructor');
        super(props);
        this.state = { count: props.count };//初始化默认状态对象
    }
    componentWillUnmount() {
        window.clearInterval(this.timer);
        console.log('componentWillUnmount');
    }
    destroy = () => {
        //卸载组件的方法
        ReactDOM.unmountComponentAtNode(document.querySelector('#root'));
    }
    render() {
        return (
            <div>
                父计数器:{this.state.count}
                <button onClick={this.destroy}>destroy</button>
            </div>
        )
    }
    //组件挂载完成
    componentDidMount() {
        console.log('3.componentDidMount 组件挂载完毕');
       //如果不清定时器,组件卸载将要报错,因为组件卸载this这个当前组件已被销毁。
        this.timer = window.setInterval(() => {
            this.setState(prevState => ({
                count: prevState.count + 1
            }));
        }, 1000);
    }
}
复制代码

相关文章:

  • oracle中两个时间类型的数据相减默认得到的是天数。
  • 阿里云禁止25端口,使用465端口发送运维邮件
  • CentOS下设置Tomcat开机自动启动操作步骤
  • android百种动画侧滑库、步骤视图、TextView效果、社交、搜房、K线图等源码
  • 柔弱的APP如何自我保护,浅谈APP防御手段,使用360加固助手加固/签名/多渠道打包/应用市场发布...
  • vue-学习系列之vue双向绑定原理
  • 答 ACM 调查问卷,限时领取阿里云代金券
  • phpmyadmin配置
  • 41、【华为HCIE-Storage】--Oceanstor9000 组网规划
  • spring对缓存的支持
  • Service Worker和HTTP缓存
  • java安全性的一种简单思路
  • ubuntu安装chrome
  • 【机器学习】--贝叶斯网络
  • Handler消息机制
  • 【347天】每日项目总结系列085(2018.01.18)
  • 【干货分享】SpringCloud微服务架构分布式组件如何共享session对象
  • 【知识碎片】第三方登录弹窗效果
  • 4月23日世界读书日 网络营销论坛推荐《正在爆发的营销革命》
  • JavaScript DOM 10 - 滚动
  • JAVA多线程机制解析-volatilesynchronized
  • Python十分钟制作属于你自己的个性logo
  • spring + angular 实现导出excel
  • Vue 重置组件到初始状态
  • 入门到放弃node系列之Hello Word篇
  • 数组大概知多少
  • 通过获取异步加载JS文件进度实现一个canvas环形loading图
  • 学习Vue.js的五个小例子
  • 浅谈sql中的in与not in,exists与not exists的区别
  • #pragma 指令
  • #stm32驱动外设模块总结w5500模块
  • (2015)JS ES6 必知的十个 特性
  • (pojstep1.1.1)poj 1298(直叙式模拟)
  • (八)五种元启发算法(DBO、LO、SWO、COA、LSO、KOA、GRO)求解无人机路径规划MATLAB
  • (附源码)ssm考试题库管理系统 毕业设计 069043
  • (论文阅读笔记)Network planning with deep reinforcement learning
  • (推荐)叮当——中文语音对话机器人
  • .bat批处理(十一):替换字符串中包含百分号%的子串
  • .bat批处理(四):路径相关%cd%和%~dp0的区别
  • .equals()到底是什么意思?
  • .NET 8.0 中有哪些新的变化?
  • .NET MVC 验证码
  • .net on S60 ---- Net60 1.1发布 支持VS2008以及新的特性
  • .NET 动态调用WebService + WSE + UsernameToken
  • .Net 路由处理厉害了
  • .net开发时的诡异问题,button的onclick事件无效
  • .NET面试题解析(11)-SQL语言基础及数据库基本原理
  • @test注解_Spring 自定义注解你了解过吗?
  • [1204 寻找子串位置] 解题报告
  • [BZOJ1008][HNOI2008]越狱
  • [element-ui] el-dialog 中的内容没有预先加载,因此无法获得内部元素的ref 的解决方案
  • [IE9] IE9 beta版下载链接
  • [LeetCode] 2.两数相加
  • [loj#115] 无源汇有上下界可行流 网络流
  • [office] 在Excel2010中设定某些单元格数据不参与排序的方法介绍 #其他#知识分享#笔记