React 새로운 삶 #16

CoderS·2021년 12월 21일
0

리액트 Remind

목록 보기
16/32

#16 바뀌어 버린 나 자신

LifeCycle Method

LifeCycle Method 는 한국말로 "생명주기 메서드" 라고 부른다.
생명주기 메서드는 컴포넌트가 브라우저 상에 나타나고 업데이트되고 사라질 때 호출되는 메서드이다. 그리고 추가로 컴포넌트에서 에러가 났을 때 호출되는 메서드 또 한 존재한다.

생명주기 메서드는 클래스형 컴포넌트에서만 사용이 가능하고, 전에 배운 useEffect 랑 비슷한 면이 있다.

우리는 리액트를 배우면서 이 개념에 너무 많은 시간을 할애하지 않는 것을 추천합니다. 앞으로는 사용할 일도 없을 것 이다. 보고 사용할 수 있는 정도만 이해하자!

링크텍스트

위에 있는 링크로 들어가서 미리 작성된 코드를 보면서 하나씩 설명을 할 것 이다.

이렇게 링크로 들어가서 해당 코드를 새로운 창으로 뛰으면 세 개의 버튼이 보일 것 이다.

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

이렇게 버튼을 눌러서 변화를 줄 때마다 생명주기 메서드들을 호출하게 된다.

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

우선...

마운트

마운트가 될 때마다 발생하는 생명주기들

  • componentDidMount
  • render
  • getDerivedStateFromProps
  • constructor

componentDidMouont

컴포넌트의 첫 번째 렌더링이 끝나고 나면 호출되는 메서드이다. 이 메서드는 호출되는 시점에서 우리가 만든 컴포넌트가 화면에 나타난 상태이다.

여기선 주로 masonry, D3 처럼 DOM 을 사용해야하는 외부 라이브러리 연동을 하거나, 해당 컴포넌트에서 필요로하는 데이터를 요청하기 위해 axios, fetch 등을 통하여 ajax 요청을 하거나, DOM 의 속성을 읽거나 직접 변경하는 작업을 진행한다.

render

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

getDerivedStateFromProps

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

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

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

알아야 할 점은 이 메서드는 컴포넌트가 처음 렌더링 되기 전에 호출되고, 그 이후 리렌더링 되기 전에도 실행한다.

constructor

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

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

업데이트

컴포넌트가 업데이트 되는 시점에 호출되는 생명주기 메서드들

  • getDerivedStateFromProps
  • shouldComponentUpdate
  • render
  • getSnapshotBeforeUpdate
  • componentDidUpdate

getDerivedStateFromProps

아까전에 마운트에서 다뤘던 메서드이면서 컴포넌트의 props 혹은 state 가 바뀌었을 때 이 메서드가 호출된다.

shouldComponentUpdate

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

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

우리가 이전에 배운 React.memo 의 역할인 최적화를 할 때 사용하는 메서드이다.

render

이번에는 생략하겠다!

getSnapshotBeforeUpdate

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

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

componentDidUpdate

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

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

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

링크텍스트

위의 링크는 getSnapshotBeforeUpdate 의 실제 사용사례를 담은 코드이다.

코드를 살펴보면...

ScrollBox.js 일부분

  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 브라우저에서는 브라우저 자체적으로 이미 구현되어있는 기능중에 하나인데, 새로운 내용을 추가했을 때 사용자의 스크롤 위치를 유지시키는 기능을하고 있다.

위의 이미지를 보면 버튼을 누를때마다, 새로운 내용이 추가되지만 스크롤은 첫 번째 내용에만 고정되어있다.

중요한 사실은 getSnapshotBeforeUpdate 은 사실 사용되는 일이 그렇게 많지 않아서 이 정도만 익혀두는게 좋다.

참고로 함수형 컴포넌트와 Hooks 를 사용해서 getSnapshotBeforeUpdate 를 대체 할 수 있는 기능은 아직 구현되지 않았다.

DOM 에 변화가 반영되기 직전에 DOM 의 속성을 확인하고 싶을 때 이 생명주기 메서드를 사용하면 된다는 것을 알아두자!

언마운트

언마운트는 마운트와 반대로 컴포넌트가 화면에서 사라지는것을 의미한다.
그리고 관련된 생명주기 메서드는 딱 하나 componentWillUnmount 이다.

componentWillUnmount

이 메서드는 컴포넌트가 화면에서 사라지기 직전에 호출된다.

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

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

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

참고 : 벨로퍼트와 함께하는 모던 리액트

느낀점 :

  • 오늘은 클래스형 컴포넌트의 생명주기 내의 특정 시점에서 실행하는 생명주기 메서드에 대해 알아봤다.
  • 오늘 배운 메서드는 앞으로 많이 쓰이지는 않지만 어느정도 개념을 익히는 것은 추천한다.
profile
하루를 의미있게 살자!

0개의 댓글