리액트 생명주기를 LifeCycle Method와 함께 알아보겠습니다.

생명 주기(Life Cycle)

클래스형 컴포넌트에서는 컴포넌트(클래스) 위주의 라이프 사이클을 갖게 되며,

컴포넌트가 생성, 업데이트, 제거될 때마다 특정 이벤트들이 발생하게 됩니다.

 

Mount

컴포넌트의 인스턴스가 생성되고 DOM에 삽입될 때 다음과 같은 메서드가 순서대로 호출됩니다.

constructor()

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

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

일반적으로 this.state에 개체를 할당하여 로컬 상태를 초기화하며,

인스턴스에 event handler 메서드를 바인딩하는데 사용합니다.

주의할 점은 super(props)를 먼저 호출하여 this.props를 정의해야 합니다.

static getDerivedStateFromProps()

기존에는 componentWillMount()였으며, props 로 받아온 것을 state로 활용하고 싶을 때 사용합니다.

이는 mount와 update 모두에서 렌더링 메서드를 호출하기 직전에 실행됩니다. (모든 렌더링 과정에 적용)

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

다른 메서드와 달리 static을 필요로 하고, this를 조회할 수 없습니다.

특정 개체를 반환하면 객체 안의 값들이 컴포넌트의 state로 설정됩니다. (null의 경우에는 예외)

render()

클래스형 컴포넌트에서 유일하게 꼭 필요한 라이프 사이클 메서드입니다.

render()

호출하게 되면 this.props와 this.state를 검증하고, 이를 다음 네 가지 타입 중 한가지로 반환합니다.

  • React elements : 일반적으로 JSX를 통해 생성
  • Arrays and fragments : multiple elements를 렌더링, fragments의 경우 추가 노드없이 자식 그룹화 가능
  • Portals : 자식을 하위 트리로 렌더링
  • String and numbers : 텍스트 노드로 렌더링
  • Booleans or null or undefined : 렌더링하지 않지만 조건으로 사용

componentDidMount()

컴포넌트가 마운트된 직후(첫 번째 렌더링)에 호출됩니다.

이 시점에는 컴포넌트가 트리에 구성된 상태이므로 주로 DOM을 활용하는 외부 라이브러리 연동, 필요한 데이터 요청 (axios), DOM 속성 변경 등의 작업을 진행합니다.

특정 이벤트를 등록하는 일도 이 시점에 진행하므로,

필요에 따라서(거의 모든 경우) componentWillUnmount() 에서 remove 해줘야 합니다.

 

Update

업데이트는 Props와 State가 변경될 때 일어나며 다음과 같은 메서드가 순서대로 호출됩니다.

static getDerivedStateFromProps()

위와 같습니다.

shouldComponentUpdate()

컴포넌트의 리렌더링 여부를 결정합니다.

shouldComponentUpdate(nextProps, nextState) {
    return true // default
}

기본적으로 true를 반환하여 리렌더링을 하지만, 조건을 걸어 리렌더링을 방지할 수 있습니다.

render()

위와 같습니다.

getSnapshotBeforeUpdate()

컴포넌트에 변화가 일어나기 직전의 DOM 상태를 조작할 수 있습니다.

이 메서드에서 반환하는 값은 이 후 호출되는 메서드인 componentDidUpdate() 에서 사용할 수 있습니다.

getSnapshotBeforeUpdate(prevProps, prevState) {
    // Are we adding new items to the list?
    // Capture the scroll position so we can adjust scroll later.
    if (prevProps.list.length < this.props.list.length) {
      const list = this.listRef.current;
      return list.scrollHeight - list.scrollTop;
    }
    return null;
  }

componentDidUpdate()

리렌더링이 끝난 직후 DOM이 재구성 된 뒤 호출되는 메서드입니다. 첫 렌더링에서는 호출되지 않습니다.

 componentDidUpdate(prevProps, prevState, snapshot) {
    // If we have a snapshot value, we've just added new items.
    // Adjust scroll so these new items don't push the old ones out of view.
    // (snapshot here is the value returned from getSnapshotBeforeUpdate)
    if (snapshot !== null) {
      const list = this.listRef.current;
      list.scrollTop = list.scrollHeight - snapshot;
    }
  }

3번째 매개 변수(snapshot)는 getSnapshotBeforeUpdate() 에서 반환된 값입니다.

기존에는 componentWillUpdatecomponentWillReceiveProps가 있었습니다.

 

Unmount

컴포넌트가 DOM에서 제거될 때 실행되는 메서드는 하나밖에 없습니다.

componentWillUnmount()

이 시점에 주로 직접 DOM에 적용했던 이벤트들과 타이머 등을 제거합니다.

 

 

 

저도 그렇지만 요즘은 클래스형 컴포넌트를 거의 사용하지 않는 추세이므로, 메서드를 활용할 일은 없지만

생명 주기에 대해 이해하고 있어야 함수형 컴포넌트를 활용할 때에도 적절한 hook을 사용할 수 있을거라 생각합니다.

 

Reference

https://legacy.reactjs.org/docs/react-component.html

 

React.Component – React

A JavaScript library for building user interfaces

legacy.reactjs.org

 

'개발일기 > Web' 카테고리의 다른 글

[React] 리액트에서 Drag&Drop으로 파일 업로드하기  (0) 2023.06.27
[React] React Hooks 이해하기  (0) 2023.06.23
[npm vs yarn] yarn은 무엇이 다를까?  (0) 2023.06.12
[Babel] 바벨?  (0) 2023.05.25
[webpack] 웹팩이란?  (0) 2023.05.18

+ Recent posts