이다닷

[React] Day 27 - LifeCycle Method 본문

React

[React] Day 27 - LifeCycle Method

이다닷 2023. 10. 10. 23:43

📢생명주기 메소드란?

  컴포넌트가 브라우저상에 나타나고, 업데이트되고, 사라지게 될 때 호출되는 메소드들이다. 

  -> 생명주기 메소드는 클래스형 컴포넌트에서만 사용이 가능하다.

 

index.js 코드 변경

import React, { useState } from "react";
import ReactDOM from "react-dom";

import "./styles.css";
import LifeCycleSample from "./LifeCycleSample";

// 랜덤 색상을 생성합니다
function getRandomColor() {
  return "#" + Math.floor(Math.random() * 16777215).toString(16);
}

function App() {
  const [color, setColor] = useState("#000000");
  const [visible, setVisible] = useState(true);

  const onClick = () => {
    setColor(getRandomColor());
  };

  const onToggle = () => {
    setVisible(!visible);
  };

  return (
    <>
      <button onClick={onClick}>랜덤 색상</button>
      <button onClick={onToggle}>토글</button>
      {visible && <LifeCycleSample color={color} />}
    </>
  );
}

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);

 

LifeCycleSample.js 추가

import React, { Component } from "react";

class LifeCycleSample extends Component {
  state = {
    number: 0,
    color: null
  };

  myRef = null; // ref 를 설정 할 부분

  constructor(props) {
    super(props);
    console.log("constructor");
  }

  static getDerivedStateFromProps(nextProps, prevState) {
    console.log("getDerivedStateFromProps");
    if (nextProps.color !== prevState.color) {
      return { color: nextProps.color };
    }
    return null;
  }

  componentDidMount() {
    console.log("componentDidMount");
  }

  shouldComponentUpdate(nextProps, nextState) {
    console.log("shouldComponentUpdate", nextProps, nextState);
    // 숫자의 마지막 자리가 4면 리렌더링하지 않습니다
    return nextState.number % 10 !== 4;
  }

  componentWillUnmount() {
    console.log("componentWillUnmount");
  }

  handleClick = () => {
    this.setState({
      number: this.state.number + 1
    });
  };

  getSnapshotBeforeUpdate(prevProps, prevState) {
    console.log("getSnapshotBeforeUpdate");
    if (prevProps.color !== this.props.color) {
      return this.myRef.style.color;
    }
    return null;
  }

  componentDidUpdate(prevProps, prevState, snapshot) {
    console.log("componentDidUpdate", prevProps, prevState);
    if (snapshot) {
      console.log("업데이트 되기 직전 색상: ", snapshot);
    }
  }

  render() {
    console.log("render");

    const style = {
      color: this.props.color
    };

    return (
      <div>
        <h1 style={style} ref={ref => (this.myRef = ref)}>
          {this.state.number}
        </h1>
        <p>color: {this.state.color}</p>
        <button onClick={this.handleClick}>더하기</button>
      </div>
    );
  }
}

export default LifeCycleSample;

 

styles.css 추가

.App {
  font-family: sans-serif;
  text-align: center;
}

 

📢마운트

  mount 명령어를 사용하면 저장 장치의 접근 경로를 원하는 위치에 생성할 수 있다.

 

➡️마운트될 때 발생하는 생명주기

 1️⃣ constructor

constructor(props) {
    super(props);
    console.log("constructor");
  }

  constructor는 컴포넌트의 생성자 메서드이다. 컴포넌트가 만들어지면 가장 먼저 실행되는 메서드이다.

 

 2️⃣ getDerivedStateFromProps

static getDerivedStateFromProps(nextProps, prevState) {
    console.log("getDerivedStateFromProps");
    if (nextProps.color !== prevState.color) {
      return { color: nextProps.color };
    }
    return null;
  }

 getDerivedStateFromProps는 props로 받아온 것을 state에 넣어주고 싶을 때 사용한다.

 -> 다른 생명주기와는 다르게 앞에 state를 필요로 하고, 이 안에서는 this를 조회할 수 없다.

 -> 여기서 특정 객체를 반환하게 되면 해당 객체 안에 있는 내용들이 컴포넌트의 state로 설정이 된다.

     하지만, null을 반환하게 되면 아무 일도 발생하지 않는다.

 -> 이 메서드는 컴포넌트가 처음 렌더링 되기 전에도 호출되고, 그 이후 리렌더링 되기 전에도 매번 실행된다.

 

 3️⃣ render

 컴포넌트를 렌더링하는 메서드이다.

 

 4️⃣ componentDidMount

 컴포넌트의 첫번째 렌더링이 마치고 나면 호출되는 메서드이다. 

  -> 이 메서드가 호출되는 시점에는 우리가 만든 컴포넌트가 화면에 나타난 상태이다.

 

📢업데이트

 

 ➡️ 업데이트가 되는 시점에 호출되는 생명주기 메서드

  1️⃣ getDerivedStateFromProps

  2️⃣ shouldComponentUpdate

shouldComponentUpdate(nextProps, nextState) {
    console.log("shouldComponentUpdate", nextProps, nextState);
    // 숫자의 마지막 자리가 4면 리렌더링하지 않습니다
    return nextState.number % 10 !== 4;
  }

 shouldComponentUpdate 메서드는 컴포넌트가 리렌더링 할지 말지를 결정하는 메서드이다.

  -> 주로 최적화 할때 사용한다.

 

  3️⃣ render

  4️⃣ getSnapshotBeforeUpdate

getSnapshotBeforeUpdate(prevProps, prevState) {
    console.log("getSnapshotBeforeUpdate");
    if (prevProps.color !== this.props.color) {
      return this.myRef.style.color;
    }
    return null;
  }

 getSnapshotBeforeUpdate 메서드는 컴포넌트에 변화가 일어나기 직전의 DOM 상태를 가져와서 특정 값을 반환하면

   -> 그 다음 발생하게 되는 componentDidUpdate 함수에서 받아와서 사용할 수 있다.

 

  5️⃣ componentDidUpdate

componentDidUpdate(prevProps, prevState, snapshot) {
    console.log("componentDidUpdate", prevProps, prevState);
    if (snapshot) {
      console.log("업데이트 되기 직전 색상: ", snapshot);
    }
  }

 componentDidUpdate 메서드는 리렌더링을 마치고, 화면에 우리가 원하는 변화가 모두 반영되고 난 뒤 호출되는 메서드이다.

  -> 3번째 파라미터로 getSnapshotBeforeUpdate에서 반환한 값을 조회할 수 있다.

사용 예시)

  - 이렇게 Click Me라는 버튼을 누르면 목록이 추가되는 페이지에서 원래대로 만들게되면 화면에서 목록이 넘어갈 때마다 스크롤이 아래로 내려가게된다.

  - 하지만, getSnapshotBeforeUpdate를 사용하면 스크롤이 내려가지않고, 고정되어있게 할 수 있다.

결과사진

 

📢언마운트

 언마운트라는 것은 컴포넌트가 화면에서 사라지는 것을 의미한다.

 

➡️ 언마운트에 관련된 생명주기 메서드

 1️⃣ componentWillUnmount

componentWillUnmount() {
    console.log("componentWillUnmount");
  }

 주로 DOM에 직접 등록했었던 이벤트를 제거하고, 만약에 setTimeout을 걸었다면, clearTime을 통하여 제거한다.

  -> 추가적으로, 외부 라이브러리를 사용하고 있고, 해당 라이브러리에 dispose 기능이 있다면 여기서 호출하면 된다.