React

[React] 리액트 컴포넌트의 생명주기 (Lifecycle)

2025-12-23 14:51


[React] 리액트 컴포넌트의 생명주기 (Lifecycle)

시작하기

리액트 컴포넌트에는 라이프사이클(Lifecycle)이 있다. 이것은 컴포넌트가 생성되고, 업데이트 되고 사라지는 일련의 과정을 말한다. 이러한 라이프 사이클은 2019년 이전 레거시한 방식이었던 클래스 컴포넌트에서 사용할 수 있었고, 최근에는 함수형 Hooks로 자동으로 다 할 수 있게 됐다.

React 컴포넌트의 라이프 사이클을 이해하기 위해서 리액트 공식문서를 참고해 다음과 같이 정리해보았다.

리액트 라이프사이클

Mount 생성 단계

컴포넌트가 처음으로 생성이 되고 실행되는 단계가 마운트 단계이다.

리액트 내부 동작 방식

1. 컴포넌트 생성 요청
2. React가 알아서 constructer() 호출
3. React가 알아서 render() 호출
4. React가 알아서 componentDidMount() 호출

constructor()

import React, { Component } from 'react';

class Counter extends Component {
  constructor(props) {
    super(props);
    this.state = {
      count: 0
    };
    this.handleClick = this.handleClick.bind(this);
  }
  ...
}

export default Counter;

getDerivedStateFromProps()

 static getDerivedStateFromProps(props, state) {
    if (props.userID !== state.prevUserID) {
      return {
        prevUserID: props.userID,
        email: props.defaultEmail
      };
    }
    return null;
  }

render()

class Greeting extends Component {
  render() {
    return <h1>Hello, {this.props.name}</h1>;
  }
}

→ 쉽게 말해 함수형 컴포넌트에서 return 이랑 같은 개념이다


componentDidMount()

➡️ 즉, 데이터 가져오거나 구독을 설정하거나 DOM 노드를 조작할때 사용

class ChatRoom extends Component {
  state = {
    serverUrl: 'https://localhost:1234',
  };

  componentDidMount() {
    this.setupConnection();
  }

  componentDidUpdate(prevProps, prevState) {
    if (
      this.props.roomId !== prevProps.roomId ||
      this.state.serverUrl !== prevState.serverUrl
    ) {
      this.destroyConnection();
      this.setupConnection();
    }
  }

  componentWillUnmount() {
    this.destroyConnection();
  }

  // ...
}

Update (업데이트 단계)

⭐️업데이트가 발생하는 조건 (=리렌더링)

  1. state가 변경될 때 (setState 호출)
  2. props가 변경될 때 (부모가 새로운 props 전달함)
  3. 부모 컴포넌트가 리렌더링 될때

shouldComponentUpdate(nextProps, nextState, nextContext)

class Rectangle extends Component {
  state = {
    isHovered: false,
  };

  shouldComponentUpdate(nextProps, nextState) {
    if (
      nextProps.position.x === this.props.position.x &&
      nextProps.position.y === this.props.position.y &&
      nextProps.size.width === this.props.size.width &&
      nextProps.size.height === this.props.size.height &&
      nextState.isHovered === this.state.isHovered
    ) {
      // 변경된 사항이 없으므로 다시 렌더링할 필요가 없습니다.
      return false;
    }
    return true;
  }

  // ...
}

componentDidUpdate()

class ChatRoom extends Component {
  state = {
    serverUrl: 'https://localhost:1234',
  };

  componentDidMount() {
    this.setupConnection();
  }

  componentDidUpdate(prevProps, prevState) {
    if (
      this.props.roomId !== prevProps.roomId ||
      this.state.serverUrl !== prevState.serverUrl
    ) {
      this.destroyConnection();
      this.setupConnection();
    }
  }

  componentWillUnmount() {
    this.destroyConnection();
  }

  // ...
}

이때 componentDidUpdate과 shouldComponentUpdate 무슨 차이점이 있을까?


Unmount (제거 단계)

componentWillUnmount()


그래서 앞서 배운 내용대로,

componentDidMount(), componentDidUpdate(), componentWillUnmount() 를 다 합친 것이 바로 useEffect를 호출하는 것과 같다.

// 함수형: useEffect 하나로 다 처리
useEffect(() => {
  // componentDidMount + componentDidUpdate

  return () => {
    // componentWillUnmount
  };
}, [deps]);

요약


참고 자료





 클래스컴포넌트라이프사이클  ReactLifeCycle  mount  React