[React] useEffect, useLayoutEffect 동작원리

Main·2023년 7월 18일
0

React

목록 보기
4/31
post-thumbnail

useEffect?

컴포넌트가 렌더링 될 때마다 Side Effect(부수 효과) 로직을 다루는 hook

기존 Class형 컴포넌트에서 렌더링 LifeCycle

  • componentDidMount : 컴포넌트가 마운트 될 때(컴포넌트가 마운트된 직후 호출됩니다.)
  • componentDidUpdate : 컴포넌트가 업데이트 될 때(컴포넌트가 업데이트된 직후 호출됩니다.)
  • componentWillUnMount : 컴포넌트가 언마운트 될 때(컴포넌트가 언마운트되기 직전 호출됩니다.)

useEffect는 위 LifeCycle들은 하나의 hook으로 관리할 수 있습니다.
이를 통해 함수형 컴포넌트에서도 쉽게 Side Effect를 다룰 수 있습니다.

Side Effect(부수효과)

함수가 실행되면서 함수 외부의 값이나 상태를 변경시키는 것을 의미

리액트의 함수형 컴포넌트는 props와 state를 기준으로 컴포넌트가 렌더링됨
컴포넌트의 렌더링과 무관한 연산들이 존재한다면 이것이 Side Effect가 된다.

무관한 연산을 컴포넌트 내에서 직접 수행하는 것은 옳지 않은 개발 방식
=> 개발자가 컴포넌트의 렌더링을 통제할 수 없기 때문

대표적인 Side Effect

  • 데이터를 가져오기 위한 외부 API 호출 시
  • 네트워크를 통해 Request를 전송할 시
  • setTimeout(), setInterval() 등의 타이머 함수 사용 시
  • 직접 컴포넌트의 DOM을 수정할 때

useEffect 사용법

  • useEffect는 두 가지의 인자를 받습니다.
  • 첫 번째 인자로는 함수를 두 번째 인자로는 dependenics array(의존성 배열)을 받습니다.
  • useEffect는 두 번째 인자를 통해 Side Effect(함수) 로직을 실행합니다.

(1) 의존성 배열이 없을 경우

  • 컴포넌트가 렌더링 될 때 마다 실행됩니다.
  • Class LifeClycle의 componentDidMount, componentDidUpdate, componentWillUnMount 모두의 역할을 합니다.
  • 렌더링 마다 Side Effect가 발생되기 때문에 의도와 다른 동작이 실행될 수 있으므로 사용시 주의가 필요합니다.
useEffect(()=>{
	console.log("컴포넌트가 렌더링 될 때 마다 실행")
})

(2) 의존성 배열이 빈 배열인 경우

  • 최초 렌더링된 이후 한번 만 렌더링됩니다.
  • Class LifeCycle의 componentDidMount와 동일한 역할을 합니다.
  • 주로 아래와 같은 경우에 사용합니다.
    • DOM를 사용해야하는 외부 라이브러리를 사용할 경우
    • axios, fetch 등 서버에 데이터를 요청할 경우
    • DOM 속성을 읽거나 변경할 경우
useEffect(()=>{
	console.log("최초 렌더링 이후 한번 만 실행")
},[])

(3) 의존성 배열에 값이 존재하는 경우

  • 의존성 배열에 들어간 값이 변경 될 때 마다 렌더링됩니다.
  • Class LifeCycle의 componentDidMount와 componentDidUpdate와 동일한 역할을 합니다.
useEffect(()=>{
	console.log("의존성 배열이 변경 될 때 마다 렌더링")
},[value])

(4) Clean-up 함수

  • Class LifeCycle의 componentWillUnMount와 동일한 역할을 합니다.
  • useEffect의 return문에서 clean-up 함수가 실행됩니다.
useEffect({
  console.log("컴포넌트 업데이트");
  retunr(()=>{
  	console.log("clean-up");
  });
},[value])

useLayoutEffect ?

실제 DOM 반영 후, 화면에 그려지는 Browser Paints screen 단계 직전 "동기적"으로 실행되는 hook

사용이유 ?

  • 기존 useEffect를 사용할 경우 DOM의 레이아웃 배치와 Paint가 끝난 후에 이펙트 함수를 호출합니다.

  • 컴포넌트들이 render 와 paint된 후에 실행되는 비동적 실행을 하게 된다. 상태값이 effect에 의존할 경우 화면의 깜빡임 같은 불편한 사용자 경험을 제공할 수 있습니다.

Render: DOM Tree 를 구성하기 위해 각 엘리먼트의 스타일 속성을 계산하는 과정
Paint: 실제 스크린에 Layout을 표시하고 업데이트하는 과정

  • useLayoutEffect를 사용하면 렌더링 후 layout과 paint 전에 동기적으로 실행되기 때문에 화면 깜빡임이 보이지 않게됩니다.

useLayoutEffect 단점

  • useLayoutEffect는 렌더링 전에 특정 행동을 수행하므로 로직이 복잡할 경우 사용자가 레이아웃을 보는데까지 시간이 오래걸린다는 단점이 있습니다.
  • useLayoutEffect는 렌더링할 상태가 effect내에서 초기화 되어야 하는 경우에만 사용하느 것이 바람직합니다.

참고 사이트

profile
함께 개선하는 개발자

0개의 댓글