프론트엔드 웹/React

React 18 useEffect render twice

세리둥절 2022. 5. 12. 09:07
반응형

✔️ 필요성

React version 18이 2022년 3월에 출시되면서 기존에 만들고 있던 프로젝트를 React 17에서 18로 업그레이드 했는데, 그 와중에 개발기에서 이상하게 render를 두 번 하는 것이 이상해서 찾아본 내용을 정리해보려고 한다.

 

 

 

 

✔️ React 18 Strict Mode

React 18에서는 추후  React 상태를 유지하면서 UI 섹션을 추가 및 제거할 수 있는 기능을 추가하고 싶습니다. 예를 들어, 사용자가 화면에서 탭으로 뒤로 이동할 때 React는 즉시 이전 화면을 표시할 수 있어야 합니다. 이를 위해 React는 이전과 동일한 구성 요소 상태를 사용하여 트리를 마운트 해제하고 다시 마운트합니다.

 

In the future, we’d like to add a feature that allows React to add and remove sections of the UI while preserving state. For example, when a user tabs away from a screen and back, React should be able to immediately show the previous screen. To do this, React would unmount and remount trees using the same component state as before.

 

이를 위한 선행 조건으로 트리를 여러번 마운트 해제하고 다시 마운트하는 과정에서 오류가 나지 않기 위해서 React는 component의 purity(순수성)가 더 중요해졌다. 

 

component의 purity와 관련해서는 아래 글을 잘 읽어본 것이 이해하는데 도움이 되었다 :) 

https://beta.reactjs.org/learn/keeping-components-pure

 

Keeping Components Pure

A JavaScript library for building user interfaces

beta.reactjs.org

 

그리고 component 혹은 effect의 순수성을 잘 확인하기 위한 방법으로 이제 Strict Mode (개발기)에서는 React는 Effect를 두 번 render해본다. 상용기에는 적용되지 않는 내용이다.

 

기존에는 effects가 한 번 생성되고 끝이였다면, effects의 purity를 검사하기 위해서 Effects가 생성되었다가 제거되었다가 다시 생성하는 일련의 과정을 거치는 것이다.

 

 

 

✔️ useEffect

useEffect를 가지고 예시를 들어보자면 아래와 같이 Tmap 컴포넌트를 추가하는 useEffect가 있을 때 cleanUp Function을 제대로 설정해주지 않으면 useEffect는 mount -> unmount -> mount 과정을 거치면서 맵이 2번 그려지게 된다.

const tmap = useRef<any>(null)

useEffect(() => {
		tmap.current = new Mmap(37.545555, 127.224, 16)
		tmap.current.addPolygon(polygon)
	}, [polygon])

 

왜 갑자기 render가 두 번 되냐고 놀랐지만 React 18의 특성을 이해하고 아래처럼 cleanUp function을 적절하게 지정했더니 문제를 해결할 수 있었다 :)

const tmap = useRef<any>(null)

	useEffect(() => {
		tmap.current = new Map(37.545555, 127.224, 16)
		tmap.current.addPolygon(polygon)
		return () => {
			tmap.current.destroy()
		}
	}, [polygon])
반응형