유저의 팔로우 목록 모달을 만들던 중, UI가 렌더가 될 때 깜빡이면서 내용이 달라졌다.
이 부분이 매우 거슬렸기 때문에 해결법을 찾았다.
결론부터 말하자면, useEffect와 useLayoutEffect는 실행 시점만 다르다.
useEffect 훅은 컴포넌트가 렌더링된 후, DOM을 업데이트 하고 paint가 완료된 후 비동기적으로 실행된다.
1useEffect(() => { 2 // 데이터 페칭 3 const fetchData = async () => { 4 const response = await fetch('/api/data'); 5 const data = await response.json(); 6 setData(data); 7 }; 8 9 fetchData(); 10},[])
데이터가 state에 반영되고 state 변경으로 인해 컴포넌트가 다시 렌더링 되기 때문에 화면이 깜빡이면서 바뀐다.
useLayoutEffect 훅은 컴포넌트가 렌더링되고 DOM이 업데이트된 직후 paint 되기 전에 동기적으로 실행된다.
1useLayoutEffect(() => { 2 if (data) { 3 const element = document.getElementById('my-element'); 4 if (element) { 5 element.style.height = `${data.length * 10}px`; // DOM 조작 6 } 7 } 8}, [data])
데이터가 state에 반영되고 state 변경으로 인해 컴포넌트가 다시 렌더링 되지만, paint가 되기 이전에 동기적으로 실행되었기 때문에 사용자는 화면의 깜빡임을 보지 않는다.
1 useLayoutEffect(() => { 2 if (modalType === 'followers') { 3 setFollowData(follower?.pages); 4 } 5 if (modalType === 'followees') { 6 setFollowData(followee?.pages); 7 } 8 }, [modalType]);
처음에는 useEffect훅을 사용했더니, 모달의 타입이 바뀔때 마다 이전 상태값이 잠깐 보였다가 바뀌었다.
useLayoutEffect 훅을 사용하여 브라우저가 화면을 다시 그리기 전에 상태값이 반영되어 깜빡임 없이 내용을 볼수 있게 된다.