개발 단계에서 리액트 컴포넌트가 두 번 렌더링 되는 이유

개발 단계에서 리액트 컴포넌트가 두 번 렌더링 되는 이유

분명 empty array([])를 전달했는데 왜 두 번 렌더링되나

리액트를 처음 접했을 땐 클래스형 컴포넌트를 작성해서 사용했었으나, 함수형 컴포넌트의 엄청난 편리함을 알아차린 뒤로는 쭉 함수형 컴포넌트를 사용해오고 있다.
클래스형 컴포넌트에서 componentDidMount에 해당하는 역할을 하는 함수형 컴포넌트의 훅은 useEffect의 두 번째 인자에 []를 넘겨주면 된다.

useEffect(() => {
    // do something...
    console.log("Hello, world!");
}, []);

문제는, Hello, world!가 두 번 출력된다는 것이었다.

React.StrictMode 컴포넌트

결론부터 말하면, 원인은 React.StrictMode 컴포넌트였다. 공식 문서를 보면, 적용된 컴포넌트가 남는 시간에 재 렌더링된다는 내용이 있다. 뿐만 아니라, 각종 이펙트 역시 다시 호출된다고 한다.

해당 컴포넌트의 조상 중 React.StrictMode가 적용된 부분을 제거하니 정상적으로 Hello, world!가 한 번만 출력되는 것을 확인할 수 있었다.

공식 문서는 항상 꼼꼼히 챙겨보자

난 시간이 촉박한 경우가 아니라면 코드를 완전히 똑같이 베끼게 되더라도 복사/붙여넣기 하지 않고 손으로 베껴 쓰는 편이다. 이번 경우도 마찬가지로, StrictMode가 적용된 컴포넌트를 구현할 때 참조한 소스 코드를 베끼는 과정에서 도대체 이 StrictMode가 뭘까? 하며 공식 문서를 본 기억이 있다.

언제나 하는 실수를 또 반복했던 나. 또 한 번 제대로 읽지 않아서 일을 두 번 하게 되었다. 심지어 저 공식 문서 링크의 내용이 아직도 기억에 남아있다. 다만, 제대로 읽지 않았기에 구글링해서 스택오버플로우의 답변을 볼 때까지 생각이 나지 않았을 뿐.

공식 문서는 항상 꼼꼼히 보고, 정확히 기억하자.

댓글

이 블로그의 인기 게시물

C# 남아도는 메모리에도 불구하고 OutOfMemoryException이 발생한다면?

USB를 뒤는 괜찮은데 앞에 꽂으면 인식이 힘들다?

MySQL 데이터 타입과 Java 데이터 타입 비교/매칭