React的父子组件生命周期

父子组件生命周期:

  “生命周期”细想之下有点浪漫主义色彩,不知道是不是从lifecycle英译过来的。作为一个前端从业者,如果让我来取,可能会取成“渲染周期”之类的,毕竟是和浏览器打交道的职业,浏览器的layout使dom树具有骨架,paint则让整个页面光亮起来。

  React 的一切都是组件,通过 React.createElement 方法来创建嵌套层级,说白了在内存中构建对象树,据此渲染到浏览器中成为dom树,这个时候一个节点是什么时候真正渲染到页面中就变得重要起来,因为只有这个时候你才能真正和浏览器环境内的对象和方法交互,同样离开的时候也需要清理监听器等防止干扰后续逻辑,因此钩子函数,也可以说是生命周期函数就有了存在的意义。

  先上代码:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta http-equiv="X-UA-Compatible" content="ie=edge" />
    <title>Document</title>
    <script crossorigin src="https://unpkg.com/[email protected]/umd/react.production.min.js"></script>
    <script crossorigin src="https://unpkg.com/[email protected]/umd/react-dom.production.min.js"></script>
    <script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
  </head>
  <body>
    <div id="app"></div>
    <div id="hollow"></div>
    <script type="text/babel">
      const { Component, Fragment } = React;
      class F extends Component {
        state = { x: ‘state before‘ };
        static getDerivedStateFromProps(getProps, getState) {
          console.log(‘F get props‘, { getProps, getState });
        }
        componentDidMount() {
          console.log(‘F did mount‘);
          setTimeout(() => {
            console.log(‘%c %s‘, ‘color:blue‘, ‘start to update state‘);
            this.setState({ x: ‘state after‘ });
          }, 2000);
        }
        shouldComponentUpdate(nextProps, nextState) {
          console.log(‘F should update‘, { nextProps, nextState });
          return true;
        }
        componentDidUpdate(prevProps, prevState) {
          console.log(‘F did update‘, { prevProps, prevState });
        }
        componentWillUnmount() {
          console.log(‘F will unmount‘, Date.now());
        }
        render() {
          return (
            <div>
              {this.props.x}
              {this.state.x}
            </div>
          );
        }
      }
      class App extends Component {
        state = { x: ‘props before ‘ };
        componentDidMount() {
          console.log(‘App did mount‘);
          setTimeout(() => {
            console.log(‘%c %s‘, ‘color:red‘, ‘start to update props‘);
            this.setState({ x: ‘props after ‘ });
          }, 2000);
        }
        componentWillUnmount() {
          console.log(‘App will unmount‘, Date.now());
        }
        render() {
          return <F {...this.state} />;
        }
      }
      setTimeout(() => {
        ReactDOM.render(‘unmount Component App at ‘ + Date.now(), app);
      }, 6000);
      ReactDOM.render(<App />, app);
    </script>
  </body>
</html>

---CodePen在线演示---

Props 和 State 相关

父组件 App 将自身的State传入了子组件 F 内,忽略挂载和卸载,列举生命周期函数:

1,getDerivedStateFromProps --

  通过浏览器打印结果可以看到,不管是组件初始化,还是更新或继承新的 state 或者 props ,最先触发的都是静态钩子函数 getDerivedStateFromProps ;

2,shouldComponentUpdate --

  在 setState 异步赋值了 state 的下一个状态后,整个子组件 F 开始收集和对比新旧状态,将新的状态输入到生命周期函数 shouldComponentUpdate 中,写明 return 的值是 truthy 还是 falsy 可以选择中断更新或者继续更新;

3,componentDidUpdate --

  在 shouldComponentUpdate 顺利进入下一步后,将执行 render 方法,更新虚拟dom树,浏览器完成渲染,在此之后旧的状态将作为参数传给 componentDidUpdate ,可以对比新状态以及是否保留旧状态;

挂载 和 卸载

componentDidMount 和 componentWillUnmount --

  观察父子组件的挂载生命周期函数,可以发现挂载时,子组件的挂载钩子先被触发;卸载时,子组件的卸载钩子后被触发;

  对于挂载钩子,一般来说,应该将子组件从上至下依次挂载到一个 fragment 上,再整体挂载到dom树中,因为频繁操作dom树不仅影响性能甚至可能影响用户体验。

  但是实际情况却并如此,我们经常在挂载函数上注册监听器,说明此时是可以与页面交互的,也就是说其实所有挂载钩子都是在父组件实际挂载到dom树上才触发的,不过是在父组件挂载后依次触发子组件的 componentDidmount ,最后再触发自身的挂载钩子,说白了,componentDidMount 其实是异步钩子。

  相反,卸载的时候父节点先被移除,再从上至下依次触发子组件的卸载钩子;

  但是我们也经常在卸载钩子上卸载监听器,这说明 componentWillUnmount 其实在父组件从dom树上卸载前触发的,先触发自身的卸载钩子,但此时并未从dom树上剥离,然后依次尝试触发所有子组件的卸载钩子,最后,父组件从dom树上完成实际卸载。

原文地址:https://www.cnblogs.com/lowki/p/11317088.html

时间: 2024-10-31 12:58:54

React的父子组件生命周期的相关文章

React组件生命周期小结

转载自:http://www.jianshu.com/p/4784216b8194 下面所写的,只适合前端的React.(React也支持后端渲染,而且和前端有点小区别,不过我没用过.) 相关函数 简单地说,React Component通过其定义的几个函数来控制组件在生命周期的各个阶段的动作. 在ES6中,一个React组件是用一个class来表示的(具体可以参考官方文档),如下: // 定义一个TodoList的React组件,通过继承React.Component来实现 class Tod

React Native组件生命周期

概述 所谓生命周期,就是一个对象从开始生成到最后消亡所经历的状态,理解空间的生命周期,是开发中必须掌握的一个知识点.就像 Android 开发中组件 一样,React Native的组件也有生命周期(Lifecycle). React Native组件的生命周期大致上可以划分为实例化阶段.存在阶段和销毁阶段.我们只有在理解组件生命周期的基础上,才能开发出高性能的app. React Native中组件的生命周期大致可以用以下图表示: 如图: 第一阶段:是组件第一次绘制阶段,如图中的上面虚线框内,

React—组件生命周期详解

React-组件生命周期详解 转自 明明的博客  http://blog.csdn.net/slandove/article/details/50748473 (非原创) 版权声明:转载请注明出处,欢迎加入QQ群(115402375)讨论!博客编写已经转移到http://blog.csdn.net/limm33 在组件的整个生命周期中,随着该组件的props或者state发生改变,它的DOM表现也将有相应的改变,一个组件就是一个状态机,对于特定的输入,它总会返回一致的输出. React为每个组件

React 的组件生命周期

React组件的state或者props发生改变后会导致这个组件重新渲染,此时DOM也会有相应的变化.其中只有Render方法在上一篇博文中提到过,就是DOM渲染时的方法.当然,只有这个方法是不够的哦!,引文在实际的开发中,开发者们需要对组件的各个阶段进行控制,这样就可以高效的进行开发了,为此,就有了React的组件生命周期的概念. 对于一个基本的React组件,可以把每一个React组件的生命周期分为初始化.挂载.更新.卸载四个阶段,在React的这四个阶段中提供了不同的方法,以方便开发者有足

React 之 组件生命周期

React 之 组件生命周期 理解1) 组件对象从创建到死亡它会经历特定的生命周期阶段2) React组件对象包含一系列的勾子函数(生命周期回调函数), 在生命周期特定时刻回调3) 我们在定义组件时, 可以重写特定的生命周期回调函数, 做特定的工作 生命周期详述1) 组件的三个生命周期状态: * Mount:插入真实 DOM * Update:被重新渲染 * Unmount:被移出真实 DOM2) React 为每个状态都提供了勾子(hook)函数 * componentWillMount()

React组件生命周期

组件的生命周期 组件有两个值State状态和PorpType属性,当状态发生变化属性就会发生变化.状态确定属性确定. 状态发生变化时会触发不同的钩子函数,从而让开发者有机会做出响应.状态可以理解为事件. 组件生命周期内 初始化-运行- 销毁 初始化阶段可以使用的钩子函数:getDefaultPorps 获取实例的默认属性/getInitialState获取实例的初始化状态/componentWillMount组件即将被渲染/ render渲染/componentDidMount组件装载之后 运行

React Native 中 component 生命周期

React Native 中 component 生命周期 转自 csdn 子墨博客  http://blog.csdn.net/ElinaVampire/article/details/51813677 (非原创) React Native中的component跟Android中的activity,fragment等一样,存在生命周期,下面先给出component的生命周期图 getDefaultProps object getDefaultProps() 执行过一次后,被创建的类会有缓存,映

ReactJS组件生命周期详述

前面已经写了一篇关于reactJS组件生命周期的博文,此篇博文是一个补充,增加了一些例子,有助于更好的理解reactJS组件. 初始化阶段能够使用的钩子函数(按照触发顺序): getDefaultProps(获取实例的默认属性)----只有第一次实例的时候调用,实例之间共享引用(属性) getInitialState(获取实例的初始状态)----初始化每个实例特有的状态 必须返回一个Object或者是Null componentWillMount(组件即将被渲染到页面)--render之前最后一

angular 组件生命周期

摘要 angular 组件生命周期和react 有很大不同 初始化 constructor ngOnChanges 当输入/输出绑定的值改变时调用 ngOnInit 在第一次 ngOnChanges 后调用 ngDoCheck 自定义的方法,检测和处理值的改变 ngAfterContentInit 在组件内容初始化之后调用 ngAfterContentChecked 组件每次检查内容时调用 ngAfterViewInit 组件相应的视图初始化之后调用 ngAfterViewChecked 组件每