ABOUT ME

-

오늘
-
어제
-
-
  • [React] 라이프 사이클(Life-Cycle) 알아보기
    Front-end/React 2020. 11. 30. 02:39

    라이프 사이클

    리액트에서 라이프 사이클은 총 3가지로 나뉘어집니다.

    • Mount: 컴포넌트 실행 후 DOM이 생성되고 웹 브라우저에 나타나는 것
    • Update: 컴포넌트를 업데이트 할 때
    • Unmount: 컴포넌트를 DOM에서 제거할 때

     

    리액트가 최근 v17로 업데이트가 되면서 기존에 존재했던 몇가지 메소드가 아예 없어졌기도 합니다.(componentWillMount, componentWillUpdate, componentWillReceiveProps)

     

    단계별로 하나씩 살펴보겠습니다.

    Mount

    DOM이 생성된 후 웹 브라우저에 최종적으로 나타나는 것을 Mount라고 합니다. 이 때 호출되는 메소드는 아래 순서대로 작동합니다.

    1. 컴포넌트 생성
    2. constuctor: 컴포넌트 생성시 호출되는 생성자
    3. getDerivedStateFormPorps: props값을 state와 동기화
    4. render: UI를 렌더링
    5. componentDidMount: 컴포넌트가 웹 브라우저에 나타난 후 호출

    Update

    컴포넌트를 업데이트 해야할 때 호출하는 메소드입니다. 그렇다면 업데이트를 하는 경우는 어떤 경우일까요?

    1. props 변경
    2. state 변경
    3. 부모 컴포넌트 리렌더링
    4. forceUpdate()를 통한 강제 렌더링

     

    위 4가지 경우에 의해 업데이트가 되면 아래 순서대로 작동합니다.

    1. props / 부모 컴포넌트 변경
    2. getDerivedStateFromProps: props값을 state와 동기화
    3. state 변경
    4. shouldComponentUpdate: true / false를 통해 리렌더링 여부를 결정하는데, 만약 false일 경우 여기서 사이클을 마침 (업데이트 할 사항이 없다고 판단)
    5. forceUpdate 호출
    6. render
    7. getSnapshotBeforeUpdate: 컴포넌트 변화를 DOM에 반영하기 전에 호출
    8. 웹 브라우저 DOM 변화
    9. componentDidUpdate: 컴포넌트 업데이트 작업이 끝나면 호출

    Unmount

    컴포넌트를 DOM에서 제거할 때 호출하는 메소드입니다.

    1. 언마운트
    2. componentWillUnmount: 컴포넌트가 웹 브라우저 상에서 사라지기 전에 호출

     

    위 세 가지의 순서들은 아래의 그림으로 보다 편하게 볼 수 있습니다.

    그렇다면 이런 라이프 사이클 메소드들이 어떤 역할을 하는지 자세히 알아보겠습니다.

    Constructor

    컴포넌트의 생성자 메소드로 컴포넌트가 생성될 때 최초로 실행합니다. 그래서 초기 state를 선언합니다.

    getDerivedStateFromProps

    v16.3 이후에 등장한 메소드로 props를 state에 동기화 시키는 역할을 합니다. Mount 단계와 props 변경시 호출됩니다.

    만약 props가 변경되었다면 이전 state값과 비교하여 특정 조건에 따른 state를 리턴하고 싶을 때 사용합니다.

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

    대표적인 예제로 바뀐 props가 이전 state와 다를 때 바뀐 props를 반환해주고, 아니면 null을 반환하여 따로 조치하지 않는 것을 의미합니다.

    render

    컴포넌트가 어떻게 그려질지를 정합니다. 라이프 사이클의 유일한 필수 메소드입니다.

    ComponentDidMount

    컴포넌트를 생성하고 첫 렌더링을 마친 후에 호출됩니다. 정말 활용성이 많은 메소드이며, 대표적으로 비동기 요청, 이벤트 등록 등을 처리하는 아주 중요한 역할을 수행합니다.

    shouldComponentUpdate

    props나 state를 변경했을 때 리렌더링을 할지 말지 여부를 정하는 메소드입니다. true / false 둘 중 하나를 반환하여 주어야 하며 만약 false가 반환될 경우 업데이트 하지 않는 것으로 간주하여 이 후 모든 메소드는 호출되지 않습니다.

    이런 특성 때문에 컴포넌트를 최적화 하는 단계에서 많이 사용됩니다.

    shouldComponentUpdate(nextProps, nextState) {
      if (nextState.number % 2 === 0) {
        return false;
      } else {
        return true;
      }
    }

    nextProps와 nextState를 통해 변화한 값에 접근하여 특정 조건을 통해 렌더링 여부를 결정할 수 있습니다.

    getSnapshotBerforeUpdate

    v16.3 이후에 등장한 메소드로 render 호출 후 DOM이 변화하기 전에 호출하는 메소드입니다. 여기서 반환되는 값은 최종적으로 업데이트 후의 메소드인 componentDidUpdate의 세 번째 파라미터로 받아서 사용할 수 있습니다.

    대표적으로 스크롤바의 위치DOM의 크기와 같은 값을 넘겨주고 싶을 때 사용합니다.

    getSnapshotBeforeUpdate(prevProps, prevState) {
      const { scrollTop, scropllHeight } = this.list;
      return { scrollTop, scrollHeight };
    }

    componentDidUpdate

    리렌더링을 완료한 후 호출됩니다. 업데이트가 끝났으므로 DOM관련된 처리를 할 수 있습니다.

    만약 getSnapshotBerforeUpdate에서 snapshot을 값을 전달 받았으면 해당 값을 가져와 처리할 수 있습니다.

    componentDidUpdate(prevProps, prevState, snapshot) {
      if (snapshot) {
        // do something...
      }
    }

    componentWillUnmount

    컴포넌트를 DOM에서 제거할 때 호출합니다. 대표적으로 이벤트, 타이머, DOM을 제거할 때 사용합니다.

    componentDidCatch

    render 메소드에서 에러가 날 때 호출됩니다. 호출 될 때 error를 받아 해당 에러 값에 따른 에러 처리를 할 때 사용합니다.

    componentDidCatch(error, info) {
      this.setState({
        error: true,
      });
    }
    
    render() {
      if (this.state.error) {
        return <div>에러</div>;
      }
    
      return <div>에러 아님</div>;
    }

     

    댓글