Iriton's log

누구든지 하는 리액트 5편: LifeCycle API 본문

Frontend/Study

누구든지 하는 리액트 5편: LifeCycle API

Iriton 2024. 10. 16. 18:50

참고 자료

 

누구든지 하는 리액트: 초심자를 위한 리액트 핵심 강좌 | VELOPERT.LOG

이 튜토리얼은 리액트를 1도 모르는 사람들을 위해 작성되었습니다. 만약에 여러분이 리액트를 배우고 싶은데, 아직 뭐가 뭔지 잘 모르겠다! 그렇다면 이 튜토리얼을 진행하고 나면 리액트가 무

velopert.com

 

LifeCycle API란 컴포넌트가 우리 브라우저에서 나타날 때, 사라질 때, 그리고 업데이트 될 때 호출되는 API이다.

 

 

컴포넌트 초기 생성

constructor

constructor(props) {
  super(props);
}

컴포넌트 생성자 함수이다. 컴포넌트가 새로 만들어질 때마다 함수가 호출된다.

 

componentDidMount

componentDidMount() {
  // 외부 라이브러리 연동: D3, masonry, etc
  // 컴포넌트에서 필요한 데이터 요청: Ajax, GraphQL, etc
  // DOM 에 관련된 작업: 스크롤 설정, 크기 읽어오기 등
}

컴포넌트가 화면에 나타나게 됐을 때 호출되는 API이다.

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

 

 

컴포넌트 업데이트

componentWillReceiverProps

componentWillReceiveProps(nextProps) {
  // this.props 는 아직 바뀌지 않은 상태
}

컴포넌트가 새로운 props를 받게 됐을 때 호출하는 API이다.

state가 props에 따라 변해야 하는 로직을 주로 작성한다.

새로 받게 될 props는 nextProps로 조회할 수 있으며, 이때 this.props를 조회하면 업데이트 되기 전의 API이니 참고해야 한다.

v16.3 부터는 UNSAFE_componentWillReceiveProps() 라는 이름으로 사용된다.

 

 

static getDerivedStateFromProps

static getDerivedStateFromProps(nextProps, prevState) {
  // 여기서는 setState 를 하는 것이 아니라
  // 특정 props 가 바뀔 때 설정하고 설정하고 싶은 state 값을 리턴하는 형태로
  // 사용됩니다.
  /*
  if (nextProps.value !== prevState.value) {
    return { value: nextProps.value };
  }
  return null; // null 을 리턴하면 따로 업데이트 할 것은 없다라는 의미
  */
}

props로 받아온 값을 state로 동기화 하는 작업을 해줘야 하는 경우에 사용된다.

setState가 아니라 특정 props가 바뀔 때 설정하고 state 값을 리턴하는 형태로 사용된다.

 

 

shouldComponentUpdate

shouldComponentUpdate(nextProps, nextState) {
  // return false 하면 업데이트를 안함
  // return this.props.checked !== nextProps.checked
  return true;
}

컴포넌트를 최적화하는 작업에서 매우 유용하게 사용된다.

리액트는 변화가 발생하는 부분만 업데이트를 해 줘서 성능이 잘 나온다. 하지만, 변화가 발생한 부분만 감지해내기 위해서 Virtual DOM에 한 번 그려 줘야 한다.

즉, 현재 컴포넌트의 상태가 업데이트 되지 않아도, 부모 컴포넌트가 리렌더링 되면 자식 컴포넌트들도 렌더링된다. 여기서 렌더링 된다는 건 render 함수가 호출된다는 걸 의미한다.

변화가 없으면 DOM 조작은 하지 않는다. 그저 Virtual DOM에만 렌더링 하는 것이다. 이 작업은 그렇게 부하가 많은 작업은 아니지만 컴포넌트가 무수히 많이 렌더링 된다면 CPU 처리량이 낭비될 수 있다.

따라서 불필요한 Virtual DOM에 리렌더링 하는 것을 방지하기 위해서 shouldComponentUpdate를 작성한다.

이 함수는 기본적으로 true를 반환한다. 조건에 따라 false를 반환하면 해당 조건에는 render 함수를 호출하지 않는다.

 

 

componentWillUpdate

componentWillUpdate(nextProps, nextState) {

}

shouldComponenetUpdate에서 true를 반환했을 때만 호출되는 API이다.

주로 애니메이션 효과를 초기화하거나 이벤트 리스너를 없애는 작업을 한다.

이 함수가 호출되고 난 다음에는 render()가 호출된다.

v16.3 이후로 deprecate 되고 getSnapshotBeforeUpdate로 대체된다.

 

 

getSnapshotBeforeUpdate

해당 API가 발생하는 시점은 다음과 같다.

  1. render()
  2. getSnapshotBeforeUpdate()
  3. 실제 DOM에 변화 발생
  4. componentDidUpdate

DOM 변화가 일어나기 직전의 DOM 상태를 가져오고, 여기서 리턴하는 값을 componentDidUpdate에서 3번째 파라미터로 받아올 수 있게 된다.

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;
    }
  }

 

 

componentDidUpdate

componentDidUpdate(prevProps, prevState, snapshot) {

}

해당 API는 컴포넌트에서 render()를 호출하고 난 다음에 발생하게 된다. 이 시점에선 this.props와 this.state가 바뀌어 있다. 그리고 파라미터를 통해 이전의 값은 preProps와 preState를 조회할 수 있다. 그리고 getSnapshotBeforeUpdate에서 반환한 snapshot 값은 세 번째 값으로 받아온다.

 

 

컴포넌트 제거

componentWillUnmount

componentWillUnmount() {
  // 이벤트, setTimeout, 외부 라이브러리 인스턴스 제거
}

주로 등록했던 이벤트를 제거한다.

예를 들어 setTimeout을 걸은 것이 있다면 clearTimeout을 통해 제거한다. 추가로 외부 라이브러리를 사용한 게 있고 해당 라이브러리에 dispose 기능이 있다면 여기서 호출하면 된다.

Comments