의도: 개발 환경에 따른 모드에 대해 알고 있는지 확인하는 질문
나의 답안
리액트의 Strict Mode는 개발 과정에서 잠재적인 버그나 비권장 패턴을 조기에 발견하기 위한 개발용 디버깅 도구입니다.
Strict Mode는 컴포넌트의 부수 작용을 탐지하기 위해 특정 라이프사이클 메서드나
useEffect같은 훅을 의도적으로 두 번 호출하여, 코드가 순수 함수처럼 동작하는지 점검합니다.
이를 통해 예상치 못한 상태 변경이나 비순수한 로직을 조기에 발견할 수 있습니다.참고로 Strict Mode는 개발 환경에서만 동작하고, 빌드된 프로덕션 코드에는 영향을 주지 않기 때문에 성능에 부담을 주지 않습니다.
따라서 초기 개발 단계에서 이를 적용하면 안정적이고 유지보수가 쉬운 코드를 작성하는 데 큰 도움이 됩니다.
주어진 답안 (모범 답안)
마치 ESLint가 필요한 이유와 같습니다.
우리는 사람이고 누구든지 완벽할 수는 없습니다.
그래서 린터가 안티 패턴을 잡아주는 것이고요.
비슷하게 Strict 모드도 개발 과정에서 발생할 수 있는 잠재적인 문제를 해결하는 데에 도움을 주는 도구입니다.
예를 든다면 잘못된 훅 사용이나 props 전달 등에 대해 경고를 줘서 해결할 수 있도록 돕습니다.그 중 대표적으로는
useEffect의 마운트가 2번 실행되는 효과가 있습니다.
마운트-언마운트-마운트의 과정을 거쳐서 개발자가 직접 수동으로 언마운트 해주지 않고도 언마운트를 테스트할 수 있도록 도와줍니다.
가끔 빠른 개발에 방해된다고 Strict 모드를 끄고 개발하시는 분도 계시지만, 저는 얻는 장점이 더 많다고 생각하여 항상 켜고 사용하고 있습니다.
React의 Strict Mode는 애플리케이션에서 잠재적인 문제를 감지하고 경고를 출력하는 개발 도구이다.
Strict Mode는 개발 환경에서만 실행되며, 프로덕션에서는 영향을 주지 않는다.
Strict Mode는 다음과 같은 React 컴포넌트의 비효율적인 코드 및 잠재적인 버그를 감지한다.
componentWillMount, componentWillReceiveProps, componentWillUpdate 같은 폐기 예정(Deprecated) 메서드의 사용을 감지한다.getDerivedStateFromProps, componentDidUpdate 등을 사용할 것을 권장한다.useEffect 없이 componentDidMount에서 직접 비동기 작업을 실행하면 경고가 발생할 수 있다.findDOMNode() 사용을 감지하고 경고한다. (React 16부터 비추천됨)ref를 이용해 DOM 요소에 접근하는 것이 권장된다.ref="myRef" 같은 문자열 ref 사용을 감지하고 경고한다.useRef 또는 콜백 ref를 사용할 것을 권장한다.Strict Mode는 <React.StrictMode> 태그로 감쌀 수 있다.
index.tsx에서 StrictMode를 루트 컴포넌트에 적용하면 된다.import React from "react";
import ReactDOM from "react-dom";
import App from "./App";
ReactDOM.createRoot(document.getElementById("root")!).render(
<React.StrictMode>
<App />
</React.StrictMode>
);function App() {
return (
<div>
<Header />
<React.StrictMode>
<MainContent /> {/* 엄격 모드 적용 */}
</React.StrictMode>
<Footer />
</div>
);
}위 예제에서는 MainContent 컴포넌트만 Strict Mode의 영향을 받는다.Strict Mode는 특정 메서드를 두 번 호출하여 부적절한 사용을 감지한다.
예를 들어, useEffect 내부의 비동기 호출이 제대로 정리되지 않으면 감지할 수 있도록 한다.
Strict Mode에서 실행 흐름 예제
import { useEffect } from "react";
function TestComponent() {
useEffect(() => {
console.log("useEffect 실행!");
return () => {
console.log("cleanup 실행!");
};
}, []);
return <div>테스트 컴포넌트</div>;
}
export default function App() {
return (
<React.StrictMode>
<TestComponent />
</React.StrictMode>
);
}
useEffect가 두 번 실행됨을 확인할 수 있다.useEffect 실행!
cleanup 실행!
useEffect 실행!Strict Mode가 useEffect를 두 번 호출하는 이유는 메모리 누수, 부적절한 클린업을 감지하기 위함이다.
이는 실제 프로덕션에서는 한 번만 실행되므로 걱정할 필요 없다.
React 18부터 Strict Mode가 개발 환경에서 더 강력하게 동작하도록 변경되었다.
useEffect와 useState 초기화가 두 번 실행된다.React 18 이전 vs. 이후 비교
| React 버전 | Strict Mode에서 useEffect 실행 방식 |
|---|---|
| React 17 이전 | 한 번만 실행됨 |
| React 18 이후 | 개발 환경에서 두 번 실행됨 |
useEffect, useState 등이 두 번 실행되는 문제가 발생할 수 있다.findDOMNode() 같은 레거시 API가 경고로 인해 사용하기 어렵다.useEffect가 두 번 실행될 수 있다는 점을 고려해야 한다.useEffect 내부에서 비동기 요청(fetch, axios 등)을 실행할 때, 의도치 않게 두 번 요청될 수 있다.useEffect(() => {
const controller = new AbortController();
fetch("https://api.example.com/data", { signal: controller.signal });
return () => controller.abort(); // Cleanup 함수 추가
}, []);findDOMNode()는 사용하지 않는다.findDOMNode()가 비추천되므로, ref를 활용하는 방식으로 대체해야 한다.const myRef = useRef(null);setState(상태 함수)를 여러 번 호출하더라도 한 번만 렌더링된다.function handleClick() {
setCount((c) => c + 1);
setName("React");
// React 18에서는 이 두 개의 상태 변경이 한 번의 렌더링에서 처리됨
}