[React] Strict 모드가 필요한 이유

jiny·2025년 3월 10일

기술 면접

목록 보기
60/78

🗣️ 리액트의 Strict 모드는 왜 필요할까요?

  • 의도: 개발 환경에 따른 모드에 대해 알고 있는지 확인하는 질문

  • 나의 답안

    리액트의 Strict Mode는 개발 과정에서 잠재적인 버그나 비권장 패턴을 조기에 발견하기 위한 개발용 디버깅 도구입니다.

    Strict Mode는 컴포넌트의 부수 작용을 탐지하기 위해 특정 라이프사이클 메서드나 useEffect 같은 훅을 의도적으로 두 번 호출하여, 코드가 순수 함수처럼 동작하는지 점검합니다.
    이를 통해 예상치 못한 상태 변경이나 비순수한 로직을 조기에 발견할 수 있습니다.

    참고로 Strict Mode는 개발 환경에서만 동작하고, 빌드된 프로덕션 코드에는 영향을 주지 않기 때문에 성능에 부담을 주지 않습니다.
    따라서 초기 개발 단계에서 이를 적용하면 안정적이고 유지보수가 쉬운 코드를 작성하는 데 큰 도움이 됩니다.

  • 주어진 답안 (모범 답안)

    마치 ESLint가 필요한 이유와 같습니다.
    우리는 사람이고 누구든지 완벽할 수는 없습니다.
    그래서 린터가 안티 패턴을 잡아주는 것이고요.
    비슷하게 Strict 모드도 개발 과정에서 발생할 수 있는 잠재적인 문제를 해결하는 데에 도움을 주는 도구입니다.
    예를 든다면 잘못된 훅 사용이나 props 전달 등에 대해 경고를 줘서 해결할 수 있도록 돕습니다.

    그 중 대표적으로는 useEffect의 마운트가 2번 실행되는 효과가 있습니다.
    마운트-언마운트-마운트의 과정을 거쳐서 개발자가 직접 수동으로 언마운트 해주지 않고도 언마운트를 테스트할 수 있도록 도와줍니다.
    가끔 빠른 개발에 방해된다고 Strict 모드를 끄고 개발하시는 분도 계시지만, 저는 얻는 장점이 더 많다고 생각하여 항상 켜고 사용하고 있습니다.


📝 개념 정리

🌟 Strict Mode(엄격 모드)란?

React의 Strict Mode는 애플리케이션에서 잠재적인 문제를 감지하고 경고를 출력하는 개발 도구이다.
Strict Mode는 개발 환경에서만 실행되며, 프로덕션에서는 영향을 주지 않는다.


🌟 Strict Mode의 주요 기능

Strict Mode는 다음과 같은 React 컴포넌트의 비효율적인 코드 및 잠재적인 버그를 감지한다.

  1. 안전하지 않은 생명주기 메서드 감지
    • componentWillMount, componentWillReceiveProps, componentWillUpdate 같은 폐기 예정(Deprecated) 메서드의 사용을 감지한다.
    • React 16 이후 getDerivedStateFromProps, componentDidUpdate 등을 사용할 것을 권장한다.
  1. 의심스러운 사이드 이펙트 감지
    • 렌더링 과정에서 부적절한 부수 효과(Side Effect)가 발생하면 경고를 출력한다.
    • 예를 들어, useEffect 없이 componentDidMount에서 직접 비동기 작업을 실행하면 경고가 발생할 수 있다.
  1. 의심스러운 Ref 사용 감지
    • findDOMNode() 사용을 감지하고 경고한다. (React 16부터 비추천됨)
    • 대신 ref를 이용해 DOM 요소에 접근하는 것이 권장된다.
  1. 레거시 String Ref 감지
    • ref="myRef" 같은 문자열 ref 사용을 감지하고 경고한다.
    • 대신 useRef 또는 콜백 ref를 사용할 것을 권장한다.
  1. 컴포넌트 상태 업데이트 감지
    • 렌더링 도중에 상태를 변경하면 불필요한 리렌더링을 유발할 수 있으므로 이를 감지하여 경고한다.
  1. 배치된 업데이트 감지
    • React가 업데이트를 자동으로 일괄 처리하지 못하는 경우를 감지하고 이를 최적화하도록 안내한다.
  1. React Concurrent Mode 준비
    • Concurrent Mode에서 비효율적으로 동작할 수 있는 패턴을 감지하여 미래의 React 버전과 호환되도록 준비한다.

🌟 Strict Mode 사용법

Strict Mode는 <React.StrictMode> 태그로 감쌀 수 있다.

  1. 전체 애플리케이션에서 사용
    Strict Mode를 애플리케이션 전체에서 사용하려면 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>
    );
  1. 특정 컴포넌트에서만 사용
    Strict Mode는 애플리케이션 전체가 아니라 특정 컴포넌트에서만 적용할 수도 있다.
    function App() {
      return (
        <div>
          <Header />
          <React.StrictMode>
            <MainContent /> {/* 엄격 모드 적용 */}
          </React.StrictMode>
          <Footer />
        </div>
      );
    }
    위 예제에서는 MainContent 컴포넌트만 Strict Mode의 영향을 받는다.

🌟 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를 두 번 호출하는 이유는 메모리 누수, 부적절한 클린업을 감지하기 위함이다.
이는 실제 프로덕션에서는 한 번만 실행되므로 걱정할 필요 없다.


🌟 Strict Mode와 React 18+의 변화

React 18부터 Strict Mode가 개발 환경에서 더 강력하게 동작하도록 변경되었다.

  1. 컴포넌트의 useEffectuseState 초기화가 두 번 실행된다.
  2. React Concurrent Mode(동시성 모드)와 더 잘 호환되도록 개선되었다.
  3. 자동 배치(Auto Batching)를 지원한다. → 여러 개의 상태 변경을 하나로 합쳐 불필요한 렌더링을 줄였다.

React 18 이전 vs. 이후 비교

React 버전Strict Mode에서 useEffect 실행 방식
React 17 이전한 번만 실행됨
React 18 이후개발 환경에서 두 번 실행됨

🌟 Strict Mode의 장단점

  • 장점
    • 코드의 안정성을 높일 수 있다.
    • 비효율적인 코드(예: 부적절한 상태 변경, 메모리 누수)를 사전에 감지할 수 있다.
    • React Concurrent Mode와의 호환성을 높일 수 있다.
    • 미래의 React 버전에서도 코드가 잘 동작하도록 대비가 가능하다.
  • 단점
    • useEffect, useState 등이 두 번 실행되는 문제가 발생할 수 있다.
    • findDOMNode() 같은 레거시 API가 경고로 인해 사용하기 어렵다.
    • Strict Mode를 적용하면 콘솔에 많은 경고가 출력될 수 있다. (이는 코드 개선을 위한 것이지만, 불편할 수도 있다.)

🌟 Strict Mode 사용 시 주의할 점

  1. useEffect가 두 번 실행될 수 있다는 점을 고려해야 한다.
    • useEffect 내부에서 비동기 요청(fetch, axios 등)을 실행할 때, 의도치 않게 두 번 요청될 수 있다.
    • 해결 방법
      • 의존성 배열을 올바르게 설정하여 불필요한 실행을 방지한다.
      • AbortController를 사용하여 불필요한 요청을 중단한다.
        useEffect(() => {
          const controller = new AbortController();
          fetch("https://api.example.com/data", { signal: controller.signal });
          
          return () => controller.abort(); // Cleanup 함수 추가
        }, []);
  1. findDOMNode()는 사용하지 않는다.
    • Strict Mode에서는 findDOMNode()가 비추천되므로, ref를 활용하는 방식으로 대체해야 한다.
      const myRef = useRef(null);
  1. React 18 이상에서는 Auto Batching을 고려해야 한다.
    • 여러 개의 상태 변경을 하나로 합쳐 렌더링 성능을 최적화하므로, 불필요한 리렌더링이 줄어든다.
    • setState(상태 함수)를 여러 번 호출하더라도 한 번만 렌더링된다.
      function handleClick() {
        setCount((c) => c + 1);
        setName("React");
        // React 18에서는 이 두 개의 상태 변경이 한 번의 렌더링에서 처리됨
      }

0개의 댓글