본문으로 바로가기

리액트의 라이프 사이클

category 개발/프론트엔드 2023. 3. 14. 00:55

이번 글에서는 리액트의 라이프 사이클(생명 주기)에 대해서 알아보도록 하겠다. 컴포넌트는 총 세종류의 라이프 사이클을 가지는데, 이때 각 사이클마다 호출되는 메서드가 다르기 때문에 메서드의 특성에 대해 알고 있어야 상황에 맞는 코드를 작성할 수가 있다. 그림으로 표현한 라이프 사이클은 다음과 같다.

Mount(마운트)

1) constructor()

컴포넌트의 생성자 메서드이다. 컴포넌트가 마운트될때 가장 먼저 실행되는 메서드로 this.propsthis.state에 접근이 가능하고 리액트 요소를 반환한다. 해당 메서드에 접근할때는 초기 설정을 하거나 state를 정할때다.

2) getDerivedStateFromProps()

props에서 받아온 값을 state에 바인딩할때 사용되는 메서드이다. 다른 사이클과 다르게 호출할때 앞에 static을 붙혀야 하며 this를 사용해서 조회할 수 없다. 여기서 특정 객체를 반환하면 해당 객체가 컴포넌트의 state로 저장된다. 만약 null을 반환할 경우 아무 일도 일어나지 않는다.

 

참고로 해당 메서드는 처음 렌더링(마운트) 되기 전과 리렌더링(업데이트) 되기 전에도 호출된다는 특징을 가지고 있다.

3) render()

컴포넌트를 실제로 렌더링 하는 메서드이다. 리액트의 렌더링 메서드는 변경되기 전 요소와 변경된 후의 요소를 비교하고 수정이 필요한 부분만 업데이트 하는 기능을 지원한다. 이것이 흔히 Virtual Dom(가상돔)이라고 불리우는 개념이다.

 

이처럼 컴포넌트에서 중추에 해당되는 중요한 메서드이므로 state를 변경하던가 해서는 해서는 안된다.

4) componentDidMount()

컴포넌트의 렌더링이 완료된 후에 호출되는 메서드로 이 메서드가 호출되는 시점에는 이미 화면에 업데이트된 컴포넌트가 나타난 이후이다. 해당 메서드에서는 DOM에 관여하는 외부 라이브러리를 실행하거나, api request를 보내는 등의 작업을 한다. 이를 위한 대표적인 훅으로 useEffect()가 존재한다.

Update(업데이트)

1) getDerivedStateFromProps()

마운트 단계에서 이미 다뤘던 메서드이다. 똑같은 작업이 수행된다고 생각하면 된다.

2) shouldComponentUpdate()

해당 메서드는 컴포넌트의 리렌더링 여부를 결정하는 메서드이다. 렌더링 된 요소가 기존의 요소와 동일한지를 확인하고 이에 대한 여부를 true또는 false로 반환한다. 이 과정에서 컴포넌트의 의존성을 트리 형태로 만들어서 어떤 컴포넌트가 리렌더링이 필요한지 파악한다. 좀더 쉬운 이해를 위해 그림과 함께 알아보도록 하자.

위는 가상의 컴포넌트 트리를 표현한 것이다. 노드 옆에 써있는 값이 초록색이면 true, 빨강색이면 false이다. SCUshouldComponentUpdate()를 호출해야 하는지에 대한 여부이고, vDOMEq는 변경되기 전의 요소와 변경된 후의 요소가 동일한지에 대한 여부이다. 마지막으로 노드가 빨간색이라면 SCU가 참이고 vDOMEq가 거짓이며, Reconciliation(재조정)이 필요하다는 의미이다.

 

C2에서는 SCU가 거짓이기 때문에 자식 노드인 C4, C5는 메서드를 실행할 필요 조차 없었다.

 

C3의 경우 SCU가 참이다. 따라서 shouldComponentUpdate()를 호출하여 해당 컴포넌트의 자식 컴포넌트들을 체크해야 한다. 자식인 C6은 SCU가 참이고 vDOMEq가 거짓이므로 리렌더링을 수행해야 한다.

 

여기서 흥미로운 부분은 C8 컴포넌트인데, 해당 컴포넌트는 SCU가 참인데도 불구하고 vDOMEq까지 참이므로 리렌더링을 하지 않는다. 왜나하면 사용자가 보는 화면은 변하지 않았기 때문이다.

3) render()

마운트에서 말했던 작업과 동일하다. 다른 점이 있다면 shouldComponentUpdate()이 true를 반환할때만 실행된다는 점이 다르겠다.

4) getSnapshotBeforeUpdate()

리렌더링이 수행되지 전의 DOM을 가져와 componentDidUpdate()에서 사용할 수 있게 해주는 메서드이다. 여기서 반환된 값은 componentDidUpdate()의 세번째 인자로 전달되게 된다.

5) ComponentDidUpdate()

리렌더링이 완료된 후 화면에 모든 변경 사항이 적용된 후에 호출되는 메서드이다. 세번째 인자에서 변경되기 이전의 DOM에 접근할 수 있다.

Unmount(해제)

언마운트는 컴포넌트가 화면에서 사라지는 것을 의미한다. 이에 관련된 사이클은 componentWillUnmount() 하나뿐이다.

1) componentWillUnmount()

컴포넌트가 화면에서 사라지기 직전에 호출되는 메서드이다. DOM에 등록했던 이벤트를 제거하거나, setTimeout이 있다면 clearTimeout을 사용해 제거하는 작업을 주로 한다. 추가적으로 외부 라이브러리를 dispose할 수 있다면 해당 메서드에서 하면 된다.

 

컴포넌트 자체에 컨텍스트를 주입해서 작은 단위의 어플리케이션으로 운영하는 환경에서는(모노레포 등) 로그아웃 했을때 사용자 캐시와 인증 토큰을 제거하는 등의 작업을 하는것도 가능하다.