25. LifeCycle Method

LifeCycle Method 는 한국어로 "생명주기 메서드" 라고 부릅니다. 생명주기 메서드는 컴포넌트가 브라우저상에 나타나고, 업데이트되고, 사라지게 될 때 호출되는 메서드들 입니다. 추가적으로 컴포넌트에서 에러가 났을 때 호출되는 메서드도 있습니다.

생명주기 메서드는 클래스형 컴포넌트에서만 사용 할 수 있는데요, 우리가 기존에 배웠었던 useEffect 랑 은근히 비슷하다고 생각하시면 됩니다. (물론 작동방식은 많이 다릅니다. 커버하지 않는 기능들도 있습니다.)

리액트를 배우시게 될 때, 이 개념에 대하여 너무 많이 시간을 쏟지 않는 것을 권장드립니다. 앞으로 사용 할 일이 별로 없을 것입니다. 다만 어떤것들이 있는지만 알아두고, 나중에 사용 해야 할 일이 있다면 매뉴얼 을 보고 사용 할 수 있는 정도만 학습해놓으면 됩니다.

이번 장에서는 따로 코드 작성은 하지 않고 이미 작성된 코드를 보면서 하나 하나 설명을 드리도록 하겠습니다.

Edit currying-bash-mrkjb

위 코드 샌드박스를 열어주세요.

위 프로젝트에서는 총 3가지 버튼이 있습니다.

  • "랜덤 색상" 버튼을 누르면 숫자의 색상이 바뀝니다.
  • "토글" 버튼을 누르면 컴포넌트가 사라지거나 나타납니다.
  • "더하기" 버튼을 누르면 숫자가 1씩 더해집니다.

이렇게 변화가 발생 할 때마다 생명주기 메서드들을 호출하게 되는데요, 이에 대하여 알아봅시다.

출처: http://projects.wojtekmaj.pl/react-lifecycle-methods-diagram/

마운트

먼저 마운트될 때 발생하는 생명주기들을 알아봅시다.

  • constructor
  • getDerivedStateFromProps
  • render
  • componentDidMount

constructor

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

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

getDerivedStateFromProps

getDerivedStateFromPropsprops 로 받아온 것을 state 에 넣어주고 싶을 때 사용합니다.

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

다른 생명주기 메서드와는 달리 앞에 static 을 필요로 하고, 이 안에서는 this 롤 조회 할 수 없습니다. 여기서 특정 객체를 반환하게 되면 해당 객체 안에 있는 내용들이 컴포넌트의 state 로 설정이 됩니다. 반면 null 을 반환하게 되면 아무 일도 발생하지 않습니다.

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

render

컴포넌트를 렌더링하는 메서드입니다. 이미 익숙하죠? :)

componentDidMount

컴포넌트의 첫번째 렌더링이 마치고 나면 호출되는 메서드입니다. 이 메서드가 호출되는 시점에는 우리가 만든 컴포넌트가 화면에 나타난 상태입니다. 여기선 주로 D3, masonry 처럼 DOM 을 사용해야하는 외부 라이브러리 연동을 하거나, 해당 컴포넌트에서 필요로하는 데이터를 요청하기 위해 axios, fetch 등을 통하여 ajax 요청을 하거나, DOM 의 속성을 읽거나 직접 변경하는 작업을 진행합니다.

업데이트

이번에는 컴포넌트가 업데이트 되는 시점에 어떤 생명주기 메서드들이 호출되는지 알아봅시다.

  • getDerivedStateFromProps
  • shouldComponentUpdate
  • render
  • getSnapshotBeforeUpdate
  • componentDidUpdate

getDerivedStateFromProps

아까전에 이미 다뤘던 메서드이지요? 컴포넌트의 props 나 state 가 바뀌었을때도 이 메서드가 호출됩니다. 잘 알아두세요!

shouldComponentUpdate

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

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

주로 최적화 할 때 사용하는 메서드입니다. 우리가 이전에 React.memo 를 배웠었지요? 그 역할과 비슷하다고 이해하시면 됩니다.

render

이미 알고있는 메서드지요? 생략하겠습니다!

getSnapshotBeforeUpdate

getSnapshotBeforeUpdate 는 컴포넌트에 변화가 일어나기 직전의 DOM 상태를 가져와서 특정 값을 반환하면 그 다음 발생하게 되는 componentDidUpdate 함수에서 받아와서 사용을 할 수 있습니다.

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

componentDidUpdate

componentDidUpdate 는 리렌더링이 마치고, 화면에 우리가 원하는 변화가 모두 반영되고 난 뒤 호출되는 메서드입니다. 3번째 파라미터로 getSnapshotBeforeUpdate 에서 반환한 값을 조회 할 수 있습니다.

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

getSnapshotBeforeUpdate 의 실제 사용사례는 다음 링크에서 확인 할 수 있는데요,

Edit getSnapshotBeforeUpdate 예제

  getSnapshotBeforeUpdate(prevProps, prevState) {
    // DOM 업데이트가 일어나기 직전의 시점입니다.
    // 새 데이터가 상단에 추가되어도 스크롤바를 유지해보겠습니다.
    // scrollHeight 는 전 후를 비교해서 스크롤 위치를 설정하기 위함이고,
    // scrollTop 은, 이 기능이 크롬에 이미 구현이 되어있는데,
    // 이미 구현이 되어있다면 처리하지 않도록 하기 위함입니다.
    if (prevState.array !== this.state.array) {
      const { scrollTop, scrollHeight } = this.list;

      // 여기서 반환 하는 값은 componentDidMount 에서 snapshot 값으로 받아올 수 있습니다.
      return {
        scrollTop,
        scrollHeight
      };
    }
  }

  componentDidUpdate(prevProps, prevState, snapshot) {
    if (snapshot) {
      const { scrollTop } = this.list;
      if (scrollTop !== snapshot.scrollTop) return; // 기능이 이미 구현되어있다면 처리하지 않습니다.
      const diff = this.list.scrollHeight - snapshot.scrollHeight;
      this.list.scrollTop += diff;
    }
  }

Chrome 브라우저에서는 브라우저 자체적으로 이미 구현되어있는 기능중에 하나인데, 새로운 내용이 추가되었을 때 사용자의 스크롤 위치를 유지시키는 기능입니다. Safari 브라우저를 포함한 일부 브라우저는 이 기능이 구현되어있지 않아서 다음과 같이 작동하게 됩니다.

새로운 항목이 위에서 추가가 되면 사용자가 보는 구간이 한칸씩 계속 밀리게 되지요? getSnapshotBeforeUpdate 를 활용하면 다음과 같이 유지를 할 수 있습니다.

getSnapshotBeforeUpdate 는 사실 사용되는 일이 그렇게 많지 않습니다. 그냥 이런게 있다.. 정도만 알아두시면 충분합니다.

참고로 함수형 컴포넌트 + Hooks 를 사용 할 때에는 이 getSnapshotBeforeUpdate 를 대체 할 수 있는 기능이 아직 없습니다. DOM 에 변화가 반영되기 직전에 DOM 의 속성을 확인하고 싶을 때 이 생명주기 메서드를 사용하면 된다는 것을 알아두세요.

언마운트

언마운트라는것은, 컴포넌트가 화면에서 사라지는것을 의미합니다. 언마운트에 관련된 생명주기 메서드는 componentWillUnmount 하나입니다.

componentWillUnmount

componentWillUnmount 는 컴포넌트가 화면에서 사라지기 직전에 호출됩니다.

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

여기서는 주로 DOM에 직접 등록했었던 이벤트를 제거하고, 만약에 setTimeout 을 걸은것이 있다면 clearTimeout 을 통하여 제거를 합니다. 추가적으로, 외부 라이브러리를 사용한게 있고 해당 라이브러리에 dispose 기능이 있다면 여기서 호출해주시면 됩니다.

정리

강의 초반에 봤던 이미지를 다시 한번 보면서 복습해봅시다.

출처: http://projects.wojtekmaj.pl/react-lifecycle-methods-diagram/

이전에 언급했듯이, 클래스형 컴포넌트를 쓰게 되는 일은 앞으로 많지 않을 것이므로, 그냥 이런게 있다 정도만 알아두시면 됩니다.

아직 다루지 않은 생명주기 메서드 중에서 componentDidCatch 라는 것도 있는데요, 이에 대해서는 다음 섹션에서 알아보도록 하겠습니다.

results matching ""

    No results matching ""