Day22-React Life Cycle 篇-上篇(介绍生命周期图 & Mounting)

这篇要介绍的是 React 元件的生命周期(Life Cycle)。

要认识生命周期的话我们可以先从这个 Life Cycle 图表网站 了解,以下两张图是从图表网站截的图,上面那张代表整个 Life Cycle 最重要的部分,下面那张则是多呈现一些比较次要的函式。

不过这些图片出现的函式,大多数都是在 class component 使用,如 componentDidMount、componentDidUpdate、componentWillUnmount...还有非函式的 constructor。functional component 需要透过 react hook 才能拥有类似生命周期的操作。

即使如此,还是可以透过图片去理解 React 的 Life Cycle,并不会影响太大。

如果你在别人介绍的 Life Cycle 文章看到 componentWillMount、componentWillUpdate 等没有出现在图片上的函式,是因为它们已经被废弃

元件生命周期三大阶段

如图所示,主要有分成三个阶段:

  • Mounting(componentDidMount) 建立元件,当元件被加入到 DOM 中时会触发
  • Updating(componentDidUpdate) 更新元件,当元件的 props 或 state 更新,重新渲染 (re-rendered) DOM 时会触发
  • Unmounting(componentWillUnmount) 注销元件,当元件从 DOM 中被移除时会触发

除了这三个阶段外,还有 Error handling,做错误处理

Mounting

在 Mounting 的部分,可以看到有五个阶段,以下将一一介绍:

第一阶段: constructor()

这个东西在 class component 使用,主要是在初始化元件的 state 和绑定一些事件,在建立 constructor() 前必须先呼叫 super(props) 这行程序去传入 props。

范例:

constructor(props) {
  super(props);
  // Don't call this.setState() here!
  this.state = { counter: 0 };
  this.handleClick = this.handleClick.bind(this);
}

第二阶段: getDerivedStateFromProps()

这个函式是静态方法(static method),无法操作 class 内的方法&变数。

静态方法牵涉到物件导向的观念,就不详细说明了。

static getDerivedStateFromProps(props, state)它接受了两个参数,更新的 props 和当前 state,我们可以使用这个函式让 props 去修改 state,最後回传的是一个要更新的 state 物件或是 null,表示不更新 state。

范例:

import React from 'react';
import ReactDOM from 'react-dom';
  
class App extends React.Component {
  render() {
    return <Child name="Tom"></Child>;
  }
}
  
class Child extends React.Component{
  constructor(props){
    super(props);
    this.state = { name: "Jean" };
  }

  static getDerivedStateFromProps(props, state) {
    if(props.name !== state.name){
      return { name: props.name };
    }
    return null;
  }

    render(){
       return (
        <div> My name is {this.state.name }</div>
       )
    }
}
                      
export default App;

如程序码所示,如果 props 的 name 和 state 的 name 不同,就更新 state 的 name 值,若相同就不更新。

另外,在 React 官网介绍 getDerivedStateFromProps()也时有说到有几种时机不适合使用这个函式:

  1. 执行 side effect
  2. 重新计算资料
  3. 重置 state

最後一点是这个函式不太常用到,如果想深入了解以上三个时机推荐阅读三个你不需要getDerivedStateFromProps的时机 这篇文章,解说的相当详细。

第三阶段: render()

这个函式一定要在 class component 内撰写,会回传以下几种类型:

  1. JSX 建立的 React element
class Example extends React.Component {
  render() {
    return <h1>Hello world!</h1>;
  }
}
  1. React fragment
class Example extends React.Component {
  render() {
    return <>Hello world!</>;
  }
}
  1. 阵列
class Example extends React.Component {
  render() {
    return [
      <div key="1">Hello</div>,
      <div key="2" >World</div>
    ];
  }
}
  1. 字串
class Example extends React.Component {
  render() {
    return "Hello world!";
  }
}
  1. Portal
class Example extends React.Component {
  render() {
    return createPortal(this.props.children, document.querySelector("body"));
  }
}
  1. Boolean
  2. null

要注意的是 render() 这个函式必须是纯粹函式,所以不能做一些变更 state 或呼叫 api 等有 side effect 的事情。

第四阶段: 更新 DOM 元素和 Refs

第五阶段: componentDidMount()

当元件呈现在网页上时就会呼叫这个函式,对应到 React hook 就是 useEffect 会进行呼叫。它用来处理那些有 DOM 元素之後才能做的事,以及更新 state、call api 取得资料。

下篇将会继续介绍未介绍到的阶段。


<<:  Day. 28 Recover Binary Search Tree

>>:  Day28-Go gRPC(上)

LeetCode 双刀流:206. Reverse Linked List

206. Reverse Linked List 这是一个「链结串列(Linked List)」的...

day6 初级系统工程师 (雷)管理眼花撩乱的机房,不是幸福

来部落格看图文并茂文章 补觉鸣诗 时间回到我入行第二年 这时才算是正式的系统工程师并开机接触机房 最...

DAY8 - BFS

今天写广度优先搜寻(BFS),BFS是一种图形搜寻演算法,在解题的时候会用来爆搜的其中一种方法 直接...

Day 26 : Linux - 档案or目录的权限该怎麽看?又该如何做更改?

如标题,今天想和大家聊聊权限这东西 权限在Linux是个非常非常重要的东西,如果你一直被termin...

JS Library 学习笔记:Three.js 初见面,在2D画面创造三维世界 (三)

在Three.js系列第一篇有提到,物件的材质与光源是3D的重要元素之一,Three.js也有相关的...