본문 바로가기

react

[React]리엑트 살펴보기5: useEffect, useLayoutEffect의 동작방식

useEffect는 함수 컴포넌트의 마운트, 업데이트, 혹은 언마운트 시점에 실행될 코드를 작성하기 위한 훅이다.

 

1. 비동기적 상태값 변경과 라이프사이클 변경주기

리엑트의 state는 비동기적으로 변경된다. 따라서, state에 의존적인 어떤 로직이 있을 때, state setter 함수 실행 후 동기적으로 작성할 수가 없다(그랬다간 이전 state로 로직이 실행되니까). 그러면 state가 변경된 이후에 로직이 실행될 수 있도록 보장할 방법이 필요하고 여기에서 useEffect 가 사용된다. 추가로 useEffect는 state 변경 후에서 컴포넌트의 마운트, 업데이트, 언마운트 시점을 골라서 실행될 수 있다.

 

2. 문법

const [state,setState]= useState()

useEffect(()=>{
console.log(state)
return ()=>{}
},[state])
  • useEffect 훅은 두 개의 인자를 가진다
  • 첫번째 인자는 실행될 함수이다.
  • 두번째 인자는 첫번째 인자인 함수가 실행될 시점을 결정하는 배열로, 의존성 배열이라 부른다.
  • 의존성 배열이 비어있으면 함수는 컴포넌트의 마운트 시점에만 실행된다.
  • 의존성 배열이 있으면, 여기 있는 값이 업데이트될 경우에도 추가적으로 함수가 실행된다.
  • return은 함수인데, 컴포넌트가 언마운트되는 시점에 실행된다. 주로, 이벤트 리스너 등의 설정된 것들을 해제할 때 사용한다. 이 함수를 클린업 이라 부른다.
  • useEffect는 사이드 효과이므로, 유지보수를 위해서는 하나의 useEffect에 하나의 기능만 작성하는 것이 좋다.

 

3. useEffect 내에서 async await 사용 

 useEffect에서 비동기 작업을 위해 promise나 await를 많이 사용하곤 한다.

필자는 await로 IIFE를 만들어 데이터를 fetch하고 loading state나 data state를 관리하는데 이 때 주의할 점이 있다.

async 구문에서 await 뒤에 오는 setState 함수는 이전의 setState와 batch update가 되지 않는다.

await 작업으로 뒤의 구문이 실행중단되면 react에서 그 앞의 state 변경 작업을 먼저 모아 실행하기 때문이다.

 

이 동작 방식을 이용하면 loading state에 사용할 수 있다. 데이터를 받아올 때 다음같이 코드를 짤 수 있다.

useEffect(()=>{

(async ()=>{
setLoaingState(true);

// 데이터 패칭
const data = await fetchingLogic(); 

setData(data);
setLoaingState(false);

})()


},[])

5. useLayoutEffect

  • useEffect 훅은 브라우저가 화면을 페인트 한 후 실행된다. 그래서 useEffect 훅을 통해 화면에 표시할 값을 변경 할 경우 처음 그려진 화면이 먼저 표시되고, 그 이후에 한번 더 화면이 바뀌게 됩니다. 이 과정에서 useEffect로 주요 ui 부분을 수정하면 화면이 번쩍이며 수정되는 문제가 발생한다.
  • useLayoutEffect 는 useEffect 훅과 다르게 리액트 돔이 업데이트 된 직후 실행되서 브라우저가 페인팅 되기 전에 실행된다. 그래서 useEffect의 위 문제를 해결할 수 있다.