Render
: DOM Tree 를 구성하기 위해 각 엘리먼트의 스타일 속성을 계산하는 과정 (Render 자체가 화면을 다시 그리는 것이 아니라, Virtual Dom을 그림으로써 어떤 부분을 바꿔야할지 계산하는 과정임)Paint
: 실제 스크린에 Layout을 표시하고 업데이트하는 과정useEffect
는 컴포넌트들이 render 와 paint 된 후 실행된다. 비동기적(asynchronous)으로 실행되며(태스크 큐에 담겼다가 실행됨) paint 된 후 실행되기 때문에, useEffect 내부에 DOM에 영향을 주는 코드가 있을 경우 사용자 입장에서는 화면의 깜빡임을 보게된다.
import { useState, useEffect } from "react";
export default function App() {
const [name, setName] = useState("");
const [age, setAge] = useState(0);
useEffect(() => {
setName("은수");
setAge(25);
}, []);
return (
<div className="App">
<h1>
안녕 내이름은 {name}이고 나이는 {age}야
</h1>
</div>
);
}
<h1>안녕 내이름은 이고 나이는 0야</h1>
를 페인트- useEffect 내부의 setName, setAge호출
- 리렌더링 수행 ->
<h1>안녕 내이름은 은수이고 나이는 25야</h1>
-> 화면 깜빡임을 볼 수 있다.
useLayoutEffect
는 컴포넌트들이 render 된 후 실행되며, 그 이후에 paint가 된다. 이 작업은 동기적(synchronous) 으로 실행됩니다. paint가 되기전에 실행되기 때문에 DOM을 조작하는 코드가 존재하더라도 사용자는 깜빡임을 경험하지 않는다.
import { useState, useLayoutEffect } from "react";
export default function App() {
const [name, setName] = useState("");
const [age, setAge] = useState(0);
useLayoutEffect(() => {
setName("은수");
setAge(25);
}, []);
return (
<div className="App">
<h1>
안녕 내이름은 {name}이고 나이는 {age}야
</h1>
</div>
);
}
- useLayoutEffect 내부의 setName, setAge호출
<h1>안녕 내이름은 은수이고 나이는 25야</h1>
를 페인트-> 화면 깜빡임이 나타나지 않는다.
useLayoutEffect는 동기적으로 실행되고 내부의 코드가 모두 실행된 후 paint작업을 거친다. 따라서 로직이 복잡할 경우 사용자가 레이아웃을 보는데까지 시간이 오래걸린다는 단점이 있다. 로직이 복잡한 경우는 다음과 같다.
data를 fetch할 때 useLayoutEffect를 쓰는 것이 가능하긴 하다. (fork 떠서 주석 해제를 하며 직접 해보기를 권장한다.)
출처
[React] useEffect 와 useLayoutEffect 의 차이는 무엇일까?
https://merrily-code.tistory.com/46