반응형
- 프로젝트: 공우 홈페이지
- 키워드: useLayoutEffect, useEffect, react hook flow
- 상황
- 공우 홈페이지에서 한글/영어 번역을 지원하고자 한다.
- 기획상 한글/영어 페이지를 각각의 URL로 분리하는 것이 아니라, 하나의 페이지에서 상태 값을 이용하여 언어를 결정한다. (다크모드와 비슷한 구조)
- 현재 언어를 localStorage에 저장해두어 새로 고침을 하거나 사이트를 벗어났다가 돌아와도 언어가 유지되도록 구현했다.
const [language, setLanguage] = useState<Language>('Korean'); // 기본 값은 Korean useEffect(() => { setLanguage(localStorage.getItem('language') ?? 'Korean'); }, []);
- 언어를 '영어'로 설정하고 새로고침을 하면, 기본값인 '한글'로 잠깐 보였다가 useEffect hook으로 인해 영어로 바뀌면서 화면이 깜빡이는 현상이 발생했다.
- 해결 방법
- React hook 중에서 useEffect를 사용한 렌더링이 문제를 일으키고 있으니, 그와 비슷한 useLayoutEffect에 대해 알아보았다.
https://ko.reactjs.org/docs/hooks-reference.html#uselayouteffect
useLayoutEffect의 내부에 예정된 갱신은 브라우저가 화면을 그리기 이전 시점에 동기적으로 수행될 것입니다. - 위의 문서를 더 자세히 이해하기 위해 React Hook을 이용하여 화면을 렌더링하는 과정을 알아보았다.
Diagram과 같이 React가 렌더링되고 -> DOM을 업데이트하고 -> 그 내용을 실제로 스크린에 paint 한 후 -> useEffect 를 실행한다.
즉, 상황 3에서 '한글'로 먼저 렌더링, DOM update, paint까지 끝낸 후에야 상태값을 '영어'로 바꾸고 리렌더링이 일어나기 때문에 깜빡임이 발생하는 것이다.
하지만 useLayoutEffect를 사용하면 렌더링 -> DOM 업데이트 -> useLayoutEffect에서 동기적으로 리렌더링 -> 그 내용을 스크린에 paint -> useEffect이 있다면 실행하기 때문에 화면 깜빡임없이 영어로 번역된 화면을 볼 수 있게 된다. - 실제로 아래 코드를 실행하면,
const [state, setState] = useState(false); console.log('render'); useEffect(() => { console.log('effect'); }, []); useLayoutEffect(() => { console.log('layout effect'); setState(!state); }, []);
render -> layout effect -> effect -> render 순서로 log가 찍히는 것을 확인할 수 있다!
- React hook 중에서 useEffect를 사용한 렌더링이 문제를 일으키고 있으니, 그와 비슷한 useLayoutEffect에 대해 알아보았다.
반응형
'프론트엔드 > React' 카테고리의 다른 글
Toast 컴포넌트 구현하기 (1) | 2022.01.26 |
---|---|
리액트에서 달팽이 모양으로 움직이는 애니메이션 만들기 (0) | 2022.01.19 |
SVGR id collision issue 해결하기 (0) | 2021.11.30 |
Firebase auth 정보를 redux로 관리하기 (0) | 2021.11.18 |
useSetRecoilState로 렌더링 최적화하기 (0) | 2021.11.15 |