Front-end/깊게 파고들기

React 생명주기 그리고 React hook

아지송아지 2022. 4. 16. 15:40

안녕하세요!

오늘은 React 생명주기와 Hook에 대해 알아보겠습니다.

 

 

React Lifecycle


보통 리액트에서 라이프사이클은 class 컴포넌트 기반의 리액트를 말하고는 합니다. 함수형 컴포넌트는 Hook을 사용합니다.

class형을 모르시더라도 쉽게 이해할 수 있게끔 설명드리겠습니다. 참고로 저도 hook만 계속 사용해 봤지만 이해하는 데는 크게 어려움 없었습니다.

 

"생성(mounting) -> 업데이트(updating) -> 삭제(unmounting)" 이러한 생명주기를 갖습니다.

그리고 각각이 "생명주기 메서드"라고 불립니다.

 

아래 메서드들을 꼭 외우지는 않으셔도 괜찮고 이해하는 식으로 넘어가도 괜찮다고 저는 생각합니다.

1. 생성(mounting)

더보기

1. constructor

컴포넌트를 새로 만들 때마다 호출되는 생성자 메서드

this.props, this.state에 접근할 수 있다

 

2. getDerivedStateFromProps()

props에 있는 값을 state에 동기화 시킬 때 사용하는 메서드

 

3. render()

UI를 렌더링하는 메서드

 

4. componentDidMount()

컴포넌트가 첫 렌더링을 마친 후 호출되는 메서드

 

2. 업데이트(updating)

더보기

1. getDerivedStateFromProps() 

마운트 과정에서 호출되며, 업데이트가 시작하기 전에 호출된다.

 

2. shouldComponentUpdate() 

props나 state가 변경되었을 때 리렌더링을 시작할지 여부를 정하는 메서드

 

3. render()
컴포넌트 리렌더링  

 

4. getSnapshotBeforeUpdate()
컴포넌트 변화를 DOM에 반영하기 전에 호출하는 메서드

 

5. componentDidUpdate()

컴포넌트 업데이트 작업이 끝난 후 호출하는 메서드

 

3. 삭제(unmounting)

더보기

componentWillUnmount()

컴포넌트를 DOM에서 제거할 때 호출되는 메서드

 

위와 같은 라이프사이클을 통해 리액트는 실행됩니다.

하지만 리액트 훅을 도입하면서 라이프사이클에도 달라진 점이 있습니다.

 

 

 

리액트 훅


도입 배경

1. 컴포넌트 사이에서 상태 로직을 재사용하기 어렵습니다.

* render props나 * 고차 컴포넌트와 같은 패턴은 코드의 추적이 어렵습니다. 훅을 사용하면 상태 관련 로직을 추상화할 수 있습니다. 계층 변화 없이 상태 관련 로직을 재사용할 수 있도록 도와줍니다.

 

*render props

컴포넌트 간 props를 이용하여 코드를 공유하는 기법

 

*고차 컴포넌트

컴포넌트 로직을 재사용하기 위한 기술

컴포넌트를 인자로 받나 새로운 컴포넌트로 반환한다. 

 

 

2. 복잡한 컴포넌트들은 이해하기 어렵습니다.

프로젝트가 커지다 보면 각 생명주기 메서드에는 관련 없는 로직이 섞여 들어가고는 합니다. 또한 복잡한 생명주기들로 인한 버그 발생도가 높습니다. 상태 관련 로직은 한 공간 안에 묶여 있기 때문에 작게 분리하는 것은 불가능합니다. 이 때문에 상태 관리 라이브러리들을 이용해왔지만 종종 너무 많은 추상화와 파일들 간의 관계 때문에 이마저도 힘들었습니다. 

 

이와 같은 문제를 해결하기 위하여 생명주기 메서드를 기반으로 쪼개기보다는 Hook을 통해 서로 비슷한 것을 하는 작은 함수의 묶음으로 컴포넌트를 나눕니다. 

 

 

 

리액트 훅의 라이프 사이클을 보겠습니다. 기존의 방식과는 차이점이 많습니다.

useState를 통해 상태변수를 선언하며, useEffect를 통해 변화들을 감지합니다. 또한 useMemo, useCallback으로 메모이제이션을 할 수 있습니다. 마지막으로 useEffect만 한 번 더 알아보겠습니다. 

 

 

useEffect

componentDidMount, componentDidUpdate, componentWillUnMount 이전에 알아보았던 라이프 사이클 메서드들을 useEffect 하나로 표현할 수 있습니다.

 

useEffect(() => {
    console.log("hello");
    return () => console.log("bye");
}, [foo])

위 useEffect는 다음 상황에서 실행됩니다.

* 첫 로드되었을 때 

* foo의 값이 변경되었을 때

* 사용하는 컴포넌트가 삭제될 때

 

 

 

 

참고 :

https://ko.reactjs.org/docs/hooks-intro.html#motivation

https://ko.reactjs.org/docs/higher-order-components.html

https://ko.reactjs.org/docs/render-props.html

https://ko.reactjs.org/docs/hooks-faq.html#can-i-skip-an-effect-on-updates