리액트의 기본 컨셉은 component
다. component 단위로 기능을 구현하고 필요한 부분에 해당 component를 사용하여, 코드를 좀 더 간결하고 유지/보수를 효율적으로 할 수 있도록 해준다.
따라서, 리액트를 사용하기 위해서는 component에 대한 이해가 필수적인데, 그중에서도 리액트의 component Lifecycle
에 대해 간단히 정리해 보려고 한다.
사실 생명주기에 관한 내용이 실제 실습을 진행하면서 코드를 작성하면서 직접적으로 영향을 주는 부분은 아니지만, 리액트에서 생명주기와 관련된 Hook 함수인 useEffect
를 사용하기 위해서는 생명주기에 대해서 기본적인 내용을 이해하는 것은 필수다.
일단 우리가 알고 있는 component에 대한 내용은, component는 처음 렌더링이 될 때 생성이 되고 dom에서 빠져나갈 때 제거가 된다는 사실이다.
이때, component가 처음 렌더링이 되는 것을 " Dom에 Mount 되었다 " 라고 표현하고, component가 dom에서 빠져나갔을 때를 " Unmount 되었다 "라고 표현한다.
즉, component가 처음 렌더링이 되어 생성되면 그것은 mount된 것이고 dom에서 빠져나가서 제거가 되면 그것을 unmount된 것이다.
리액트의 생명주기는 위에서 말한 mount와 unmount 주기를 말한다.
정리하자면, 리액트의 Lifecycle은 Component가 Dom에 Mount될 때부터 Dom에서 Unmount될 때까지의 기간이라고 보면 된다.
사실, 리액트의 component의 생명주기를 이해하기 위해서는 더 깊은 개념을 살펴봐야 하지만 component에 대한 기본적인 이해를 바탕을 목적으로 정리하는 내용이기 때문에 핵심적인 부분들만 다루게 되었다.
만약에 더 자세한 내용을 알고 싶다면 아래 링크를 접속해서 해당 사이트에서 소개하는 개념들을 살펴보면 될 것 같다!
✅ 참고하면 좋을 사이트 https://projects.wojtekmaj.pl/react-lifecycle-methods-diagram/
앞서 생명주기에 대해서 아주 간단히 살펴보았는데, 리액트로 코드를 작성하면 생명주기 개념을 바탕으로 component를 구현해야 하는 경우가 있다.
이때 함수 component의 경우에는 react에서 제공하는 Hook 함수를 통해서 간단히 구현이 가능하지만 class의 경우에는 생명주기 메서드를 사용해서 따로 component를 구현해야 한다.
대표적으로 사용하는 메서드는 다음 3가지다.
1. componentDidMount - 처음 렌더링
2. componentDidUpdate - 업데이트되어 리렌더링
3. componentWillUnmount - 제거
위의 3가지 메서드를 사용해서 class component의 생명주기를 간단히 설명하자면, (1) 먼저 처음에 class의 constructor가 해당 component를 초기화하게 된다. (2) 그 후 render 메서드를 통해서 1번째 렌더링이 실행되고 (3) react dom에 업데이트가 되면 componentDidMount 메서드가 실행되게 된다. 이를 통해서 첫 렌더링으로 dom이 생성되었다는 것을 알리는 것과 비슷한 맥락이라고 생각하면 될 것 같다. 그 후에 (4) 만약 특정 state가 변경이 되면 다시 re-rendering 되어 dom이 업데이트되고 이를 감지하고 (5) componentDidUpdate 메서드가 실행되는 것이다. 마지막으로 (6) component dom에서 제거되면 componentWillUnmount 메서드가 실행된다.
이처럼, 만약 class component를 사용한다면 위의 3가지 메서드를 통해서 생명주기에 따른 코드를 작성할 수 있게 된다.
하지만, 위의 3가지 메서드를 사용해 생명주기에 따른 코드를 작성하다 보면 코드가 약간은 복잡해지고 나중에 유지/보수하기에도 불편하다는 단점이 있다.
따라서, class component의 단점으로 최근에는 대부분 함수 기반의 component를 사용하고 있는데 처음 언급한 것과 같이 함수 component에서는 react의 Hook 함수인 useEffect
를 통해서 생명주기에 따른 코드를 간결하게 작성 가능하다.
useEffect는 react에서 제공하는 생명주기와 관련된 Hook 함수다.
앞서 살펴본 class component의 생명주기 메서드를 useEffect를 통해서 사용할 수 있는데, 기본적인 함수 형태는 아래와 같다.
useEffect (() => {
}, [option])
useEffect는 기본적으로 2개의 인자를 받는데, 1번째 인자는 함수이고 2번째는 배열을 받는다. 이때 2번째 인자인 배열은 opntion이다. 즉, 필수적인 인자는 아니라는 것이다.
단, 2번째 인자인 배열 인자가 있느냐 없느냐에 따라 어떤 생명주기 흐름을 제어하는지 결정하게 된다.
(1) 빈 배열
useEffect (() => {
}, [])
만약 위의 경우과 같이 빈 배열을 사용하게 되면 이는 componentDidMount처럼 동작하게 된다. 즉, 첫 렌더링 할 때 1번째 인자로 받은 함수가 1번 실행되는 것이다.
(2) 배열 X
useEffect (() => {
})
만약 위의 코드처럼 배열을 넘겨주지 않으면 componentDidMount + componentDidUpdate처럼 동작하게 된다. 즉, 첫 렌더링 할 때와 컴포넌트 내부의 특정 값들이 변경될 때 1번째 인자로 넘긴 함수가 실행되는 것이다.
하지만, 위의 경우는 모든 값이 변경될 때마다 렌더링이 되기 때문에 성능 측면에서 굉장히 비효율적이다.
그래서, 보통의 경우에는 배열 안에 특정 값을 정의를 해주는데 지정한 값이 변경될 때만 렌더링 될 수 있도록 하는 것이다.
(3) 배열 안에 값 넣어주기
useEffect (() => {
}, [state1, state1])
만약 값이 변경될 때 업데이트되어 렌더링 될 수 있도록 하고 싶을 때는 위의 코드와 같이 변경을 감지할 데이터를 미리 설정해 준다. 즉, state1과 state2의 값이 변경될 때만 업데이트되어 다시 렌더링 되는 것이다.
class component보다 함수 component를 사용하는 것이 최근의 리액트 흐름이지만, class component 기반으로 된 서비스들이 아직 많이 있기 때문에 해당 서비스들의 코드를 이해하기 위해서는 class component에 대해서도 학습하고 이해할 필요가 있다.
따라서, 생명주기에 대한 기본적인 개념을 익히고 class에서 생명주기 메서드를 사용하는 경우를 살펴보고 익히는 것 역시 중요하다고 생각한다!