useLayoutEffect > DOM > 생명주기

2023. 5. 30. 14:03개발/토막난 상식

반응형

 이 훅은 React 컴포넌트가 렌더링된 후, 실제 DOM 업데이트가 일어나기 전에 동기적으로 실행됩니다.

 이것은 레이아웃 계산 등의 작업을 수행하기에 적합한 시점입니다.

 

렌더링
  |
  v
가상 DOM 생성
  |
  v
useLayoutEffect 호출
  |
  v
useLayoutEffect 내부 코드 실행
  |
  v
실제 DOM 업데이트
  |
  v
사용자에게 업데이트된 DOM 보여짐

 

DOM은 Document Object Model의 약자로, 웹 페이지의 구조화된 표현을 제공하는 프로그래밍 인터페이스입니다. DOM은 HTML, XML 또는 XHTML 문서의 각 요소를 나타내는 객체들로 구성됩니다.

웹 브라우저는 웹 페이지를 로드할 때, 해당 페이지의 HTML 문서를 파싱하여 DOM 트리를 생성합니다. DOM 트리는 요소(element), 속성(attribute), 텍스트 등의 정보를 포함하고 있으며, 이를 통해 웹 페이지의 구조와 내용에 접근하고 조작할 수 있습니다.

 

DOM은 웹 페이지의 구조를 트리 형태로 표현합니다. 최상위에는 문서 전체를 나타내는 document 객체가 있으며, document 객체의 자식 요소로는 html 요소가 있습니다. 이어서 html 요소의 자식 요소로 head 요소와 body 요소가 포함됩니다. body 요소에는 다시 다양한 요소들이 중첩되어 구성될 수 있습니다.

DOM은 JavaScript와 같은 스크립팅 언어를 사용하여 웹 페이지의 요소에 접근하고 조작할 수 있는 API를 제공합니다. 예를 들어, DOM을 사용하여 특정 요소의 내용을 변경하거나 스타일을 수정할 수 있습니다. 또한, 이벤트 처리, 동적 생성 및 삭제, 데이터의 읽기 및 쓰기 등을 할 수 있습니다.

요약하자면, DOM은 웹 페이지의 구조를 표현하는 객체 모델로서, 웹 페이지의 요소에 접근하고 조작할 수 있는 인터페이스를 제공합니다.

 

리액트에서 사용되는 "가상 DOM(Virtual DOM)"은 리액트의 핵심 개념 중 하나입니다. 가상 DOM은 리액트가 UI 업데이트를 효율적으로 처리하는 방법입니다.

일반적으로 웹 애플리케이션에서 UI는 실제 DOM(Document Object Model)으로 표현됩니다. 실제 DOM은 웹 페이지의 구조를 표현하는 객체 트리입니다. DOM 업데이트는 요소의 추가, 삭제, 속성 변경 등의 작업을 수행할 때마다 실제 DOM을 조작하고 렌더링을 업데이트하는 작업을 의미합니다.

하지만 DOM 업데이트는 비용이 많이 들기 때문에, 많은 요소가 변경될 때마다 모든 DOM 조작을 수행하면 성능 저하가 발생할 수 있습니다. 이를 해결하기 위해 리액트는 가상 DOM을 사용합니다.

가상 DOM은 메모리 상에 존재하는 가벼운 복제품이라고 생각할 수 있습니다. 리액트는 가상 DOM을 사용하여 실제 DOM과 동기화하고, 변경된 부분만을 감지하여 최소한의 DOM 조작만을 수행합니다. 이를 통해 성능을 향상시키고, 효율적인 UI 업데이트를 가능하게 합니다.

리액트의 가상 DOM 작동 방식은 다음과 같습니다:

리액트 컴포넌트가 렌더링될 때, 컴포넌트 트리의 각 노드에 대응하는 가상 DOM 트리가 생성됩니다.
가상 DOM 트리는 이전 렌더링의 결과와 비교하여 변경된 부분을 찾습니다.
변경된 부분은 실제 DOM에 반영됩니다. 이때, 최소한의 DOM 조작만을 수행하여 효율적인 업데이트를 이룹니다.
가상 DOM은 리액트의 주요 장점 중 하나로, 애플리케이션의 성능을 향상시키고 복잡한 UI 상태 관리를 단순화하는 데 도움을 줍니다. 가상 DOM은 리액트가 빠른 업데이트 처리와 효율적인 렌더링을 가능하게 하여 사용자 경험을 향상시키는 데 중요한 역할을 합니다.

 

 

최적화 방식에서 효과적

 

 

 

정리 

useLayoutEffect와 useEffect는 두 가지 리액트 훅으로, 컴포넌트의 라이프사이클에서 특정 작업을 수행하는 데 사용됩니다. 그러나 두 훅은 동작하는 시점과 방식에 차이가 있습니다.

실행 시점:
useLayoutEffect: 브라우저에 업데이트를 반영하기 직전에 동기적으로 실행됩니다. 즉, DOM 업데이트 전에 실행됩니다.
useEffect: 브라우저 업데이트 이후에 비동기적으로 실행됩니다. 즉, DOM 업데이트 이후에 실행됩니다.


동기/비동기 실행:
useLayoutEffect: 동기적으로 실행되기 때문에, 훅 내부의 작업이 완료될 때까지 브라우저 업데이트가 차단됩니다. 따라서 레이아웃 계산이 필요한 작업에 적합합니다.
useEffect: 비동기적으로 실행되기 때문에, 훅 내부의 작업이 브라우저 업데이트와 상호작용하지 않고 백그라운드에서 실행됩니다.


최적화:
useLayoutEffect: useLayoutEffect 훅 내부에서 반환된 함수는 컴포넌트가 언마운트되거나 다시 렌더링될 때 실행됩니다. 이를 통해 정리(clean-up) 작업이 가능합니다.
useEffect: useEffect 훅 내부에서 반환된 함수도 언마운트 시나 다시 렌더링될 때 실행됩니다. 그러나 useEffect의 경우 브라우저 업데이트 이후에 실행되므로, 반환된 함수는 최신 상태의 DOM을 참조할 수 있습니다.

 

사용 사례:
useLayoutEffect: DOM 요소의 크기나 위치를 측정하거나 조작하기 위해 사용됩니다. 레이아웃 계산이 필요한 작업에 적합합니다.
useEffect: 데이터 가져오기, 이벤트 처리 등과 같은 비동기적인 작업이 필요한 경우에 사용됩니다. 실제 DOM 업데이트 이후에 작업을 수행하면 되는 경우에 유용합니다.

 

 

 

 

 

 

clean-up 작업은 컴포넌트가 마운트 해제될 때(언마운트) 또는 업데이트 전에 수행해야 하는 정리 작업을 말합니다.

리액트 컴포넌트는 생명주기 동안 여러 번 렌더링되거나 마운트/언마운트될 수 있습니다. 이 때 clean-up 작업은 다음과 같은 상황에서 유용합니다:

컴포넌트 언마운트: 컴포넌트가 DOM에서 제거될 때 실행되어야 하는 작업이 있을 때 clean-up 작업을 수행합니다. 이는 메모리 누수를 방지하거나, 이벤트 핸들러 등을 제거하여 불필요한 리소스 소모를 막는 데 도움을 줍니다.

컴포넌트 업데이트: 컴포넌트가 업데이트될 때 이전 값과 비교하여 clean-up 작업을 수행할 수 있습니다. 예를 들어, 이전 상태와 현재 상태 간의 차이를 비교하여 필요한 리소스를 해제하거나, 이전 이벤트 리스너를 업데이트하는 등의 작업을 수행할 수 있습니다.

clean-up 작업은 보통 useEffect나 useLayoutEffect 훅에서 반환하는 함수를 통해 수행됩니다. 이 함수는 컴포넌트가 언마운트되거나 업데이트되기 전에 호출되어야 합니다. 이를 통해 컴포넌트의 생명주기에 맞게 리소스를 해제하거나 정리할 수 있습니다.

예를 들어, useEffect 훅에서 이벤트 리스너를 등록한 경우, clean-up 작업을 위해 해당 이벤트 리스너를 제거하는 함수를 반환하여 이벤트 리스너를 정리할 수 있습니다. 이를 통해 컴포넌트가 마운트 해제될 때 해당 이벤트 리스너가 자동으로 제거됩니다.

clean-up 작업은 리소스 관리와 메모리 누수 방지에 중요한 역할을 합니다. 컴포넌트의 생명주기에 맞게 필요한 정리 작업을 수행하여 애플리케이션의 성능과 안정성을 향상시킬 수 있습니다.

 

 

 

 

 

마운트(Mount)와 언마운트(Unmount)는 리액트 컴포넌트의 생명주기(lifecycle) 개념에 기반한 용어입니다. 컴포넌트의 마운트는 컴포넌트가 DOM에 삽입되어 화면에 나타나는 것을 의미하고, 언마운트는 컴포넌트가 DOM에서 제거되어 화면에서 사라지는 것을 의미합니다.

마운트(Mount):

마운트는 컴포넌트의 인스턴스가 생성되고 DOM에 삽입될 때 발생합니다.

 


마운트 순서: constructor() -> static getDerivedStateFromProps() -> render() -> componentDidMount()

constructor(): 컴포넌트의 인스턴스가 생성됩니다. 이 단계에서 초기 상태(state)를 설정하거나 메서드를 바인딩할 수 있습니다.
static getDerivedStateFromProps(): 컴포넌트가 생성되고 리렌더링될 때 호출됩니다. 부모 컴포넌트로부터 전달받은 속성(props)을 사용하여 상태(state)를 업데이트할 수 있습니다.
render(): 컴포넌트의 UI를 렌더링합니다. 이 단계에서 가상 DOM을 생성하고 실제 DOM에 반영할 JSX 코드를 반환합니다.
componentDidMount(): 컴포넌트가 DOM에 삽입된 후에 호출됩니다. 이 단계에서는 외부 API와의 상호작용이나 비동기 작업, 이벤트 리스너 등을 등록할 수 있습니다.

 


마운트 단계에서 컴포넌트는 초기화 작업을 수행하고, 필요한 데이터를 가져오거나 이벤트 리스너를 등록하는 등의 작업을 처리할 수 있습니다.
컴포넌트가 마운트된 후에는 componentDidMount() 메서드가 호출되어 추가적인 작업을 수행할 수 있습니다. 예를 들어, 외부 라이브러리와의 통합, 네트워크 요청 등의 비동기 작업을 처리할 수 있습니다.
언마운트(Unmount):

언마운트는 컴포넌트가 DOM에서 제거되어 화면에서 사라질 때 발생합니다.
언마운트 순서: componentWillUnmount()

componentWillUnmount(): 컴포넌트가 DOM에서 제거되기 직전에 호출됩니다. 이 단계에서는 리소스 정리(clean-up) 작업을 수행합니다. 예를 들어, 이벤트 리스너를 제거하거나 타이머를 해제할 수 있습니다.


언마운트 단계에서 컴포넌트는 리소스 정리(clean-up) 작업을 수행합니다. 이는 이벤트 리스너 제거, 타이머 해제, 네트워크 요청 취소 등의 작업을 포함할 수 있습니다.
컴포넌트가 DOM에서 제거된 후에는 더 이상 화면에 영향을 주지 않으며, 재사용되지 않는 상태가 됩니다.
마운트와 언마운트는 컴포넌트의 생명주기 메서드를 사용하여 관리할 수 있습니다. 리액트는 컴포넌트의 마운트와 언마운트 시점에 호출되는 여러 생명주기 메서드를 제공합니다. 예를 들어, componentDidMount() 메서드는 마운트 단계에서 호출되고, componentWillUnmount() 메서드는 언마운트 단계에서 호출됩니다. 이러한 생명주기 메서드를 사용하여 컴포넌트의 초기화와 정리 작업을 수행할 수 있습니다.

 

 

 

 

 

리액트 컴포넌트의 생명주기(lifecycle)는 컴포넌트가 생성되고 화면에 렌더링되며, 업데이트되고 제거되는 일련의 단계를 말합니다. 생명주기 메서드는 이러한 단계에서 호출되는 특정한 함수들입니다. 이를 통해 컴포넌트의 동작을 제어하고, 초기화, 데이터 로딩, 이벤트 처리 등의 작업을 수행할 수 있습니다.

리액트 v16.3 이전까지의 생명주기는 세 가지 카테고리로 구분할 수 있었습니다: 마운트(Mount), 업데이트(Update), 언마운트(Unmount). 리액트 v16.3 이후부터는 몇 가지 변경이 있어 다음과 같이 구분됩니다:

마운트(Mount):

컴포넌트가 생성되고 DOM에 삽입될 때의 단계입니다.
constructor(), static getDerivedStateFromProps(), render(), componentDidMount() 등의 메서드가 해당 단계에서 호출됩니다.
업데이트(Update):

컴포넌트가 업데이트되는 단계입니다. 업데이트는 다양한 이벤트에 의해 발생할 수 있습니다. 예를 들어, 상태(state)의 변경, 속성(props)의 변경 등이 해당됩니다.
static getDerivedStateFromProps(), shouldComponentUpdate(), render(), getSnapshotBeforeUpdate(), componentDidUpdate() 등의 메서드가 해당 단계에서 호출됩니다.
언마운트(Unmount):

컴포넌트가 DOM에서 제거되어 사라지는 단계입니다.
componentWillUnmount() 메서드가 해당 단계에서 호출됩니다.
생명주기 메서드를 사용하여 컴포넌트의 특정 단계에서 원하는 작업을 수행할 수 있습니다. 예를 들어, 초기 상태 설정, 외부 데이터 로딩, 이벤트 리스너 등록, 리소스 정리 등을 처리할 수 있습니다. 이를 통해 컴포넌트의 동작을 제어하고 원하는 동작을 구현할 수 있습니다.

리액트 v17부터는 일부 생명주기 메서드가 사용되지 않거나 권장되지 않는 상태로 표시되었으며, 새로운 생명주기 메서드인 getDerivedStateFromProps()와 componentWillReceiveProps() 대신에 componentDidUpdate()와 useEffect()를 사용하는 것이 권장됩니다. 이는 컴포넌트의 동작을 더 명확하고 예측 가능하게 만들기 떄문입니다.

반응형