프론트엔드를 하겠다고 마음 먹기 전, useEffect는 그냥 컴포넌트가 마운특라 되면 호출되는 아이라는 것만 알고 있었다.
맞는 말이긴 한데 렌더링 과정의 비밀을 알아버렸다. 비밀은 어그로입니다 죄송합니다.
결론부터 말하면은 호출되는 순서 차이다.
아래 공식문서 사진을 보면 파란줄 표시한 곳에 답이 나와있다. "렌더링이 완료된 후에 수행 될 것입니다."
프로젝트 하면서 그냥 당연하게 여겼던 것이 이것 때문이었다. 아래 예시 코드를 보면 그냥 컴포넌트가 마운트 되면 useEffect를 이용해서 데이터를 받아 오고 출력하는 과정이다.
export default function Test() {
const [data, setData] = useState(null);
useEffect(() => {
fetch('https://jsonplaceholder.typicode.com/todos/1')
.then((response) => response.json())
.then((json) => setData({ ...json }));
}, []);
return (
<>
<div style={{ margin: '4rem auto' }}>{`${data?.id}, ${data?.title}`}</div>
</>
);
}
아래는 실행 한 것인데. 처음에는 undefined 였다가. useEffect가 호출되어 가져온 데이터가 출력이 된다. "렌더링이 완료된 후에 수행 될 것입니다." 이 말이 이것을 위한 빌드업 이었다. 이 마법이 일어나는 이유는 hook-flow 에서 볼 수 있는데 앞에서 말했다 시피 Browser paints screen과정이 일어난 다음에 useEffect가 호출 되기 때문이다.
Browser paints screen이 뭐냐면 여기서는 간단하게 하고 다음에 각 잡고 포스팅 하겠습니다.
아래와 같은 과정을 거쳐 부라우저는 렌더링이 됩니다. 이걸 Critical rendering path라고 부르는데.
html 파일이 css 파일과 만나 렌더트리가 형성된 후 브라우져에 어떤 크기로 배치될지 계산이 되고 난 다음 같은 레이어 끼리 묶어서 차곡 차곡 쌓아서 렌더링이 된다고 보면 됩니다.
어쨋든. 이 어마무시한 과정이 일어난 후 useEffect가 호출된다는 거에요. 그래서 앞에 코드에서 undefined가 살짝 보인 후 요청한 데이터가 출력된 거랍니다.
그래서 이 useLayoutEffect라는 녀석이 등장했습니다. 라고 하면서 useLayoutEffect 결과 영상을 보여드릴려 했는데 제가 잘 못했습니다. (밑에는 제 심정)
예시를 네트워크 통신을 이용하면 안 됐었는데 죄송합니다. 여러분 지금까지 쓴게 아까워서 계속 쓰겠습니다. 감사합니다. 의미전달은 전혀 상관없지만 비동기 함수를 사용하면 이벤트 루프때문에 undefined가 뜨는겁니다. 죄송합니다. 아래는 변경된 코드입니다.
export default function Test() {
const [data, setData] = useState(undefined);
useEffect(() => {
setData({ id: 1, title: '123123' });
}, []);
return (
<>
<div style={{ margin: '4rem auto' }}>{`${data?.id}, ${data?.title}`}</div>
</>
);
}
위의 코드 결과는 아래처럼 됩니다. 중간에 undefined 보이시죠? 이거 보여드릴려구 편집까지 했답니다 ^^ 다시 본론으로 useLayoutEffect는 오른쪽 사진에 보이는 분홍색 박스의 표시처럼 렌더링 전에 호출되는 아이입니다. 한번 그러는지 봅시다.
아래는 useLayoutEffect를 적용한 코드입니다.
export default function Test() {
const [data, setData] = useState(null);
useLayoutEffect(() => {
setData({ id: 1, title: '123123' });
}, []);
return (
<>
<div style={{ margin: '4rem auto' }}>{`${data?.id}, ${data?.title}`}</div>
</>
);
}
새로고침을 해도 undefined가 보이지 않네요 ^^ 이상입니다. 감사합니다.
결론 : useEffect는 렌더링 후에 실행되고 useLayoutEffect는 렌더링 전에 호출된다.
'프론트엔드 > React' 카테고리의 다른 글
Portals (0) | 2023.03.11 |
---|---|
연속된 커스텀 훅(훅인마) (0) | 2023.03.09 |
리액트 hydrate (0) | 2023.02.21 |
React에서 innerHTML을 !?!?! (0) | 2023.01.24 |
Masonry layout(react) (0) | 2023.01.23 |