JiYoung Dev πŸ–₯

[React] Lifecycle (2023.05.24) λ³Έλ¬Έ

full stack/React

[React] Lifecycle (2023.05.24)

Shinjio 2023. 5. 24. 17:50

 

LifeCycle

 

 

ν˜„μž¬ reactλŠ” node.js μ„œλ²„ μœ„μ—μ„œ λŒμ•„κ°€κ³  있음. node.jsλŠ” μ‹±κΈ€μŠ€λ ˆλ“œλ‘œ μž‘μ—…μ„ μ§„ν–‰ν•˜λŠ” ν”„λ‘œμ„ΈμŠ€κ°€ ν•˜λ‚˜ 밖에 μ—†μŒ. κ·Έλ ‡κΈ° λ•Œλ¬Έμ— μœ„μ—μ„œ μ•„λž˜λ‘œ μ½”λ“œκ°€ μž‘μ„±λœ μˆœμ„œλŒ€λ‘œ μ§„ν–‰λ˜λŠ” javaμ™€λŠ” 달리 μ½”λ“œ 쀑간에 쑰건문과 같은 무거운 μž‘μ—…μ΄ 있으면 μœ„μ—μ„œ μ•„λž˜λ‘œ μ½”λ“œ μž‘μ„± μˆœμ„œλŒ€λ‘œ μž‘μ—…μ„ μ§„ν–‰ν•˜μ§€ μ•Šκ³ , κ°€λ²Όμš΄ μž‘μ—…λΆ€ν„° 진행 ν›„ 무거운 μž‘μ—…μ„ μ§„ν–‰μ‹œν‚΄. 

 

λ”°λΌμ„œ Reactμ—μ„œλŠ” μœ„μ—μ„œ μ•„λž˜λ‘œ μˆœμ„œλŒ€λ‘œ μ½”λ“œλ₯Ό μž‘μ„±ν•œλ‹€κ³  ν•΄μ„œ μ›ν•˜λŠ” λŒ€λ‘œ μž‘μ—…μ΄ μ‹€ν–‰λ˜μ§€ μ•ŠμŒ. Reactsms μ»΄ν¬λ„ŒνŠΈκ°€ μ‹€ν–‰λ˜κ±°λ‚˜, μ—…λ°μ΄νŠΈ λ˜κ±°λ‚˜, μ‚­μ œλ  λ•Œ νŠΉμ • μ΄λ²€νŠΈκ°€ λ°œμƒν•¨. μ΄λŸ¬ν•œ React의 νŠΉμ„±μ„ 생λͺ…μ£ΌκΈ°(LifeCycle)이라고 ν•˜λ©°, Reactλ₯Ό 톡해 μš°λ¦¬κ°€ μ›ν•˜λŠ” λŒ€λ‘œ μ›ΉνŽ˜μ΄μ§€κ°€ μž‘λ™ν•˜κ²Œ λ§Œλ“€κΈ° μœ„ν•΄μ„œλŠ” lifecycle을 μ΄ν•΄ν•˜κ³  이λ₯Ό λ°”νƒ•μœΌλ‘œ κ°œλ°œμ„ μ§„ν–‰ν•˜λŠ” 것이 ν•„μš”ν•¨ 

 

🎈 React LifeCycle λΆ„λ₯˜

μ»΄ν¬λ„ŒνŠΈ 생성-λ³€ν™”-μ œκ±°κΉŒμ§€ μ£ΌκΈ°λ₯Ό μž‘μ„ 수 있음

>> 이λ₯Ό ν† λŒ€λ‘œ λ‚΄κ°€ μ›ν•˜λŠ” μ‹œμ μ— μ½”λ“œκ°€ λ“€μ–΄κ°ˆ 수 μžˆλ„λ‘ ν•  수 있음

 

 

ReactλŠ” μ»΄ν¬λ„ŒνŠΈ 기반의 Viewλ₯Ό μ€‘μ‹¬μœΌλ‘œ ν•œ 라이브러리. Viewλ₯Ό μ€‘μ‹¬μœΌλ‘œ ν•˜κΈ° λ•Œλ¬Έμ— 보톡 νŽ˜μ΄μ§€κ°€ Rendering 되기 전인 μ€€λΉ„ κ³Όμ •μ—μ„œ μ‹œμž‘ν•˜μ—¬ νŽ˜μ΄μ§€μ—μ„œ μ‚¬λΌμ§ˆ λ•Œ 끝이 남

 

πŸ“– Mount(마운트)

μ»΄ν¬λ„ŒνŠΈκ°€ 생성될 λ•Œ λ°œμƒν•˜λŠ” 생λͺ…μ£ΌκΈ°

 

βš™οΈ constructor

- μ»΄ν¬λ„ŒνŠΈ μƒμ„±μž λ©”μ„œλ“œ, μ»΄ν¬λ„ŒνŠΈκ°€ μƒμ„±λ˜λ©΄ κ°€μž₯ λ¨Όμ € μ‹€ν–‰λ˜λŠ” λ©”μ„œλ“œ. 이 λ©”μ„œλ“œμ—μ„œλŠ” 초기 state 값을 μ •μ˜ν•  수 있음 (useState)

- 화면이 λ Œλ”λ§ 되기 μ „ 졜초의 μˆœκ°„ 

 

βš™οΈ render

- μ»΄ν¬λ„ŒνŠΈλ₯Ό λ Œλ”λ§ν•  λ•Œ ν•„μš”ν•œ λ©”μ„œλ“œλ‘œ μœ μΌν•œ ν•„μˆ˜ λ©”μ„œλ“œ

- constructor λ©”μ„œλ“œ μ‹€ν–‰ 된 이후 μ‹€ν–‰

- JSXκ°€ HTML둜 λ³€ν™˜λ˜μ–΄ μ›ΉλΈŒλΌμš°μ €μ— λ‚˜νƒ€λ‚¨

- 화면이 λ Œλ”λ§ λ˜λŠ” 쀑

- render λ©”μ„œλ“œλŠ” μ»΄ν¬λ„ŒνŠΈκ°€ λ‘œλ”©λ  λ•Œμ—μ„œ μ‹€ν–‰λ˜μ§€λ§Œ μ»΄ν¬λ„ŒνŠΈμ˜ 데이터(state, props)κ°€ μ—…λ°μ΄νŠΈ λ˜μ—ˆμ„ λ•Œμ—λ„ λ™μž‘ν•¨. λ”°λΌμ„œ render λ©”μ„œλ“œμ—μ„œ setStateλ‚˜ propsλ₯Ό λ³€ν™”μ‹œν‚€λŠ” λ©”μ„œλ“œλ₯Ό κ°€λŠ₯ν•˜λ©΄ μˆ˜ν–‰ν•˜μ§€ μ•ŠλŠ” 것을 μΆ”μ²œ

 

βš™οΈ componentDidMount

 

- μ»΄ν¬λ„ŒνŠΈμ˜ 첫번째 λ Œλ”λ§μ΄ 마치고 λ‚˜λ©΄ ν˜ΈμΆœλ˜λŠ” λ©”μ„œλ“œ. 이 λ©”μ„œλ“œκ°€ ν˜ΈμΆœλ˜λŠ” μ‹œμ μ—λŠ” μš°λ¦¬κ°€ λ§Œλ“  μ»΄ν¬λ„ŒνŠΈκ°€ 화면에 λ‚˜νƒ€λ‚œ μƒνƒœ

- ν™”λ©΄ λ Œλ”λ§ 된 직후

- 데이터λ₯Ό 가지고 μ˜€λŠ”μΌμ„ 함 (API κ°€μ Έμ˜€κΈ° λ“±)

  ν”„λ‘ νŠΈμ—”λ“œμ™€ λ°±μ—”λ“œκ°€ ν•¨κ»˜ μ£Όκ³ λ°›λŠ” 정보듀을 API라고 함

  ex. 둜그인 정보

 

πŸ“– Update(μ—…λ°μ΄νŠΈ)

μ»΄ν¬λ„ŒνŠΈκ°€ μ—…λ°μ΄νŠΈ λ˜λŠ” μ‹œμ μ˜ 생λͺ…μ£ΌκΈ° 

stateλ‚˜ props의 λ³€κ²½ 유무둜 μ—…λ°μ΄νŠΈλ₯Ό νŒλ‹¨

 

βš™οΈ componentDidUpdate

 

 

μ»΄ν¬λ„ŒνŠΈμ˜ 변경이 μ™„λ£Œλ˜μ—ˆμ„ λ•Œ μˆ˜ν–‰λ˜λŠ” λ©”μ„œλ“œ

render λ©”μ„œλ“œκ°€ μ‹€ν–‰λ˜μ–΄ μ—…λ°μ΄νŠΈ 된 state, props와 μ—…λ°μ΄νŠΈ 되기 전인 state, propsλ₯Ό 가지고 비ꡐ μž‘μ—…

 

πŸ“– UnMount(μ–Έλ§ˆμš΄νŠΈ)

μ»΄ν¬λ„ŒνŠΈκ°€ ν™”λ©΄μ„Έμ–΄ μ‚¬λΌμ§ˆ λ•Œ 생λͺ…μ£ΌκΈ°

 

βš™οΈ componentWillUnmount

μ»΄ν¬λ„ŒνŠΈκ°€ μ‚¬λΌμ§ˆ λ•Œ μˆ˜ν–‰λ˜λŠ” λ©”μ„œλ“œ

 

🎈 ν•¨μˆ˜ν˜• μ»΄ν¬λ„ŒνŠΈμ—μ„œμ˜ 라이프사이클 

 

κΈ°μ‘΄ ReactλŠ” 클래슀 μ»΄ν¬λ„ŒνŠΈλ‘œ μ‚¬μš©λ˜μ—ˆμŒ.

(ν•¨μˆ˜ν˜• μ»΄ν¬λ„ŒνŠΈμ—μ„œλŠ” state 관리와 라이프사이클을 μ‚¬μš©ν•  수 μ—†μ—ˆμŒ) 

 

κ·ΈλŸ¬λ‚˜ 점점 ν•¨μˆ˜ν˜• μ»΄ν¬λ„ŒνŠΈλ₯Ό 많이 μ‚¬μš©ν•˜κ²Œ 됨

ν•¨μˆ˜ν˜• μ»΄ν¬λ„ŒνŠΈλ₯Ό 많이 μ‚¬μš©ν•˜κ²Œ 된 계기 쀑 ν•˜λ‚˜ : react Hook

 

 

/** rcc : class component μƒμ„±ν•˜λŠ” 단좕킀 * 

* React Hookμ΄λΌλŠ” κΈ°λŠ₯듀이 μƒκ²¨λ‚˜λ©΄μ„œ 
* κΈ°μ‘΄ Function μ»΄ν¬λ„ŒνŠΈμ—μ„œ μ‹€ν–‰λ˜μ§€ μ•Šμ•˜λ˜ λ¦¬μ•‘νŠΈμ˜ μ€‘μš” μš”μ†Œλ“€μ„ 
* Function μ»΄ν¬λ„ŒνŠΈμ—μ„œ μ‚¬μš©ν•  수 있게 λ˜μ—ˆμŒ 

* * ex) κ³Όκ±°μ—λŠ” LifeCycle 같은 μ€‘μš”ν•œ κ°œλ…μ„ Function Componentμ—μ„œ μ‚¬μš©ν•  수 μ—†μ—ˆμŒ
*     react Hook이 μƒκ²¨λ‚˜κ²Œ λ˜λ©΄μ„œ μ΄μ œλŠ” Function componentμ—μ„œλ„ LifeCycle을 μ‚¬μš©ν•  수 있게 λ˜μ—ˆμŒ
* *     react Hook : use~ μ‹œμž‘ν•˜λŠ” 것듀
*     ex. useState, useRef, useContext ... etc (κΈ°μ‘΄μ—λŠ” μ‚¬μš©λͺ»ν–ˆλ˜ 것듀) * */

 

πŸ“– 클래슀 μ»΄ν¬λ„ŒνŠΈλ‘œ 라이프사이클 ν™•μΈν•˜κΈ°

 

 

import React, { Component } from "react";

/** rcc : class component μƒμ„±ν•˜λŠ” 단좕킀
 *
 * React Hookμ΄λΌλŠ” κΈ°λŠ₯듀이 μƒκ²¨λ‚˜λ©΄μ„œ
 * κΈ°μ‘΄ Function μ»΄ν¬λ„ŒνŠΈμ—μ„œ μ‹€ν–‰λ˜μ§€ μ•Šμ•˜λ˜ λ¦¬μ•‘νŠΈμ˜ μ€‘μš” μš”μ†Œλ“€μ„
 * Function μ»΄ν¬λ„ŒνŠΈμ—μ„œ μ‚¬μš©ν•  수 있게 λ˜μ—ˆμŒ
 *
 * ex) κ³Όκ±°μ—λŠ” LifeCycle 같은 μ€‘μš”ν•œ κ°œλ…μ„ Function Componentμ—μ„œ μ‚¬μš©ν•  수 μ—†μ—ˆμŒ
 *     react Hook이 μƒκ²¨λ‚˜κ²Œ λ˜λ©΄μ„œ μ΄μ œλŠ” Function componentμ—μ„œλ„ LifeCycle을 μ‚¬μš©ν•  수 있게 λ˜μ—ˆμŒ
 *
 *     react Hook : use~ μ‹œμž‘ν•˜λŠ” 것듀
 *     ex. useState, useRef, useContext ... etc (κΈ°μ‘΄μ—λŠ” μ‚¬μš©λͺ»ν–ˆλ˜ 것듀)
 *
 */
export default class Ex01 extends Component {
  // stateλŠ” 화면을 λ§Œλ“€κΈ° 이전에 λ§Œλ“€μ–΄μ Έμ•Ό 함 >> κ·Έλž˜μ•Ό 화면에 띄어쀄 수 있음
  // state 관리λ₯Ό 1번으둜 (constructor)

  componentDidMount() {
    /**componentDidMount : 화면이 마운트됨(λ Œλ”λ§μ΄ λλ‚¬μŒ)
     * >> API call(ajax, fetch, axios...) λ“± 데이터λ₯Ό λ°›μ•„μ˜€λŠ” 무거운 μž‘μ—…λ“€μ„ 진행함
     * >> 무거운 μž‘μ—…μ€ 화면을 μš°μ„  보여쀀 ν›„ μ§„ν–‰λ˜λ„λ‘!
     */
    console.log("3. componentDidMount - ν™”λ©΄ λ Œλ”λ§ μ™„λ£Œ!");
  }

  componentDidUpdate() {
    /**값이 λ³€κ²½λ˜μ–΄ 갱신이 μΌμ–΄λ‚œ 직후에 호좜! */
    console.log("**값이 λ³€κ²½λ˜μ—ˆμŠ΅λ‹ˆλ‹€!**");
  }

  constructor() {
    console.log("1. constructor - μ΅œμ΄ˆμƒμ„±");
    /**constructor : μƒμ„±μž
     * 화면이 λ Œλ”λ§λ˜κΈ° 전에 μ΄ˆκΈ°ν™” ν•΄μ€˜μ•Ό ν•  것듀을 μ •μ˜
     * state, λ³€μˆ˜, ν•¨μˆ˜ λ“± 값을 μ΄ˆκΈ°ν™”ν•  λ•Œ μ‚¬μš©ν•¨
     * 화면이 λ Œλ”λ§ 되기 이전 (κ°€μž₯ 졜초의 단계)
     * κ·œμΉ™ :
     */
    super();
    //state 관리 : {}μ•ˆμ— λ‚΄κ°€ 관리해쀄 λͺ¨λ“  state μž…λ ₯
    this.state = {
      num: 0,
    };

    //μ‚¬λ³Έν•¨μˆ˜λ₯Ό λ§Œλ“€μ–΄μ€Œ
    this.handleIncrement = this.handleIncrement.bind(this);
    this.handleDecrement = this.handleDecrement.bind(this);
    this.handleReset = this.handleReset.bind(this);
  }

  //   ν•¨μˆ˜λŠ” μ •ν™•ν•œ μ‹œμ μ΄ μžˆλŠ”κ²Œ μ•„λ‹ˆλΌ ν˜ΈμΆœν•˜λ©΄ μ‚¬μš©ν•˜λŠ” 것
  handleIncrement() {
    console.log("handle Increment Function");
    this.setState({
      num: (this.state.num += 1),
    });
  }

  handleDecrement() {
    console.log("hanle Decrement Function");
    this.setState({
      num: this.state.num > 0 ? (this.state.num -= 1) : 0,
    });
  }

  handleReset() {
    console.log("handle Reset");
    this.setState({
      num: 0,
    });
  }

  render() {
    /**render : 화면을 λ Œλ”λ§ν•  λ•Œ
     * >> 화면을 κ΅¬μ„±ν•˜λŠ” μš”μ†Œλ₯Ό μž‘μ„±ν•˜λ©΄ 됨! (DOMμš”μ†Œ/HTMLμš”μ†Œ)
     */
    console.log("2. render - 화면이 λ Œλ”λ§ λ˜λŠ”μ€‘...");
    return (
      <div>
        <h1>Class Component : {this.state.num}</h1>
        <button onClick={this.handleIncrement}>+1</button>
        <button onClick={this.handleDecrement}>-1</button>
        <button onClick={this.handleReset}>reset</button>
      </div>
    );
  }
}

 

🎈 ν•¨μˆ˜ν˜• μ»΄ν¬λ„ŒνŠΈμ—μ„œ λΌμ΄ν”Œ 사이클 μ‚¬μš©ν•˜κΈ° : useEffect

 

 

둜직 : componentdidMount λŒ€μ²΄

 

 

[state] : componentDidUpdate λŒ€μ²΄

 

 

ν•¨μˆ˜ν˜• μ»΄ν¬λ„ŒνŠΈμ—μ„œ 라이프사이클을 ν™œμš©ν•  수 μžˆλŠ” useEffect μ‚¬μš©

 

import React, { useState, useEffect } from "react";

const Ex02 = () => {
  // 1. constructorλ₯Ό λŒ€μ²΄
  // ν•¨μˆ˜ ν˜ΈμΆœμ‹œ μžλ™μœΌλ‘œ ν•¨μˆ˜ μ΄ˆκΈ°ν™”λ₯Ό 진행함
  // >> state, λ³€μˆ˜ μ΄ˆκΈ°ν™”
  console.log("1. constructorλ₯Ό λŒ€μ²΄!");
  const [num, setNum] = useState(0);

  /**3. ν™”λ©΄ κ°±μ‹  직후 - componentDidMount >> useEffect λ¦¬μ•‘νŠΈ ν›… μ‚¬μš©
   * useEffect(()=>{}, [])
   * 첫번째 인자 : μ½œλ°±ν•¨μˆ˜ (ν•¨μˆ˜ μ•ˆμ— λ“€μ–΄μžˆλŠ” ν•¨μˆ˜)
   * λ‘λ²ˆμ§Έ 인자 : λΉ„μ–΄μžˆλŠ” λ°°μ—΄
   * >> 화면에 λ Œλ”λ§μ΄ 끝났을 λ•Œ (Mount) 첫번째 μΈμžμ— μžˆλŠ” μ½œλ°±ν•¨μˆ˜λ₯Ό 호좜!
   * API Callκ³Ό 같은 무거운 μž‘μ—…μ„ 진행
   */
  useEffect(() => {
    console.log("3. ν™”λ©΄ λ Œλ”λ§ μ™„λ£Œ!");
  }, []);

  /**4. 값이 λ³€ν™”ν–ˆμ„ λ•Œ - componentDidUpdate >> useEffect λ¦¬μ•‘νŠΈ ν›… μ‚¬μš©
   * useEffect(()=>{}, [state])
   * 첫번째 인자 : μ½œλ°±ν•¨μˆ˜
   * λ‘λ²ˆμ§Έ 인자 : λ³€ν™”λ₯Ό 감지할 state
   * ex. useEffect(()=>{}, [num]) >> numμ΄λΌλŠ” stateκ°€ λ³€ν• λ•Œλ§ˆλ‹€ μ½œλ°±ν•¨μˆ˜λ₯Ό 호좜
   */
  useEffect(() => {
    console.log("** 값이 λ³€ν™”ν–ˆμŠ΅λ‹ˆλ‹€!");
  }, [num]);

  return (
    //2. renderλ₯Ό λŒ€μ²΄  >> returnλ¬Έ μ•ˆ
    <div>
      {console.log("2. renderλ₯Ό λŒ€μ²΄ >> returnλ¬Έ μ•ˆ")}
      <h1>Function Component : {num}</h1>
      <button
        onClick={() => {
          setNum(num + 1);
        }}
      >
        +1
      </button>
      <button
        onClick={() => {
          setNum(num - 1);
        }}
      >
        -1
      </button>
    </div>
  );
};

export default Ex02;

 

 

ν΄λž˜μŠ€λŠ” ν•œλ²ˆμ‹€ν–‰λ˜λ©΄ 계속 ν˜ΈμΆœλ˜μ§€ μ•ŠμŒ > μƒμ„±μž 1번만 생성

ν•¨μˆ˜ν˜•μ€ ν˜ΈμΆœν•΄μ„œ μ‚¬μš©ν•˜λŠ” κ²ƒμ΄λ―€λ‘œ 계속 μƒμ„±μžκ°€ 생성됨