- useEffect, useLayoutEffect의 차이점은?
-> effect가 실행되는 시점
useEffect
useLayoutEffect
코드상으로 useEffect가 useLayoutEffect보다 먼저 오는데도 불구하고 useLayoutEffect가 먼저 실행됨
useEffect는 컴포넌트가 화면에 그려지고 난 이후에 실행이 됨
첫 번째 인자인 effect는 비동기적으로 실행됨 (다른 작업을 블로킹 하지 않고 적절한 때에 실행이 됨)
컴퓨터 프로그래밍에서 특정 작업이 완료될 때까지 다른 작업을 중단시키는 것
주로 동기적(synchronous) 작업에서 발생하고, 해당 작업이 완료될 때까지 프로그램의 실행이 멈추게 됨
예를 들면, 파일을 읽는 동기적 함수가 있다면 파일을 모두 읽을 때까지 프로그램의 실행을 멈추게 되고 파일 읽기가 완료된 후에 다른 작업을 수행할 수 있음
비동기적(asunchronous) 작업은 블로킹을 피함
호출된 후 즉시 제어권을 반환하며, 작업이 완료되면 콜백함수나 promise를 통해 결과를 처리함
이는 프로그램이 다른 작업을 계속 수행할 수 있게 해줌
useLayoutEffect의 effect는 컴포넌트가 화면에 그려지기 이전에 실행이 됨
위 코드의 실행 순서를 보면 useLayouteffect가 실행이 되고, 화면이 그려지고, useEffect가 실행이 됨
update 버턴을 클릭하면 업데이트 된 컴포넌트가 화면에 그려지기 이전에 useLayoutEffect가 먼저 실행이 되고, 컴포넌트가 화면에 그려지고, useEffect가 실행됨
useLayoutEffect는 effect가 동기적으로 실행됨
해당 작업이 실행되는 동안 다른 작업은 실행되지 못하게 블로킹함
(useLayoutEffect가 실행되는 동안은 화면이 업데이트 되지 않음)
- 따라서, useLayoutEffect를 과하게 사용하거나 이 안에서 무거운 작업을 한다면 APP의 성능을 저하시킬 수 있음
import { useEffect, useRef, useState } from "react";
// 외부에서 데이터를 가져오는 API라고 가정
function getNumbers() {
return [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15];
}
function UseLayOutEffectHook2() {
const [numbers, setNumbers] = useState([]);
const ref = useRef(null);
useEffect(() => {
const nums = getNumbers();
setNumbers(nums);
}, []);
// 페이지가 로딩되자마자 제일 마지막 숫자까지 보이도록 스크롤이 맨 아래까지 내려가도록 작업
// useEffect를 통해 getNumbers로부터 받아온 nums가 setNumbers를 통해 numbers라는 state 안에 들어가면
// 자동으로 스크롤을 내려주는 코드 작성하기
// numbers가 아직 로딩되지 않았을 때는 스크롤을 내려주지 않기
useEffect(() => {
if (numbers.length === 0) {
return;
}
ref.current.scrollTop = ref.current.scrollHeight;
}, [numbers]);
return (
<div
ref={ref}
style={{
height: "300px",
border: "1px solid blue",
overflow: "scroll",
}}
>
{numbers.map((number, idx) => (
<p key={idx}>{number}</p>
))}
</div>
);
}
export default UseLayOutEffectHook2;
- 딜레이 없이 정확한 시점에 UI 변화를 보여주고 싶다면 useEffect가 아니라 useLayoutEffect를 사용하자
- 이처럼 사용자에게 보여지는 UI 변화를 더 정교하게 다뤄야 될 때는 useLayoutEffect를 사용하면 됨
useLayoutEffect는 effect가 모두 완료될때까지 화면업데이트가 발생하지 못하도록 블로킹하기 때문에 불필요하게 남용하면 프로그램 성능에 큰 무리가 갈 수 있음
만약 useEffect와 useLayoutEffect중 고민하는 경우,
대부분의 경우 useEffect를 사용하는 것이 더 좋은 판단일 때가 많음