ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • React에서 순환 참조 문제 해결하기
    Front-end/React.js 2024. 10. 23. 18:13
    반응형

    React 프로젝트를 진행하다 보면 종종 순환 참조(Circular Dependency) 문제에 직면할 때가 있습니다. 순환 참조는 두 개 이상의 모듈이 서로를 직접적으로 또는 간접적으로 참조하는 경우 발생합니다. 이 문제는 런타임 에러를 발생시키고 애플리케이션이 제대로 동작하지 않게 만듭니다.

    이 글에서는 React에서 React.lazy()import()를 사용하여 순환 참조 문제를 해결하는 방법에 대해 알아보겠습니다.

    문제 상황

    React와 Material-UI(MUI)를 사용하여 커스텀 텍스트 필드와 셀렉트 필드 컴포넌트를 개발하던 중 순환 참조(circular dependency) 문제에 직면했습니다. 구체적으로, StyledSelectField 컴포넌트가 CustomTextField를 참조하고, 동시에 CustomSelectFieldStyledSelectField를 참조하는 상황이었습니다.

    // StyledCustomField.tsx
    import { CustomTextField } from "./CustomTextField";
    
    // CustomSelectField.tsx
    import { StyledCustomField } from "./CustomSelectField.styles";

    이로 인해 다음과 같은 오류가 발생했습니다:

    Uncaught ReferenceError: Cannot access 'CustomTextField' before initialization
        at CustomSelectField.styles.tsx:4:41

    해결 방법: React.lazy()와 동적 import 활용

    이 문제를 해결하기 위해 React의 lazy() 함수와 동적 import()를 사용했습니다. 다음은 해결 코드입니다:

    import { styled } from "@mui/material";
    import { lazy } from "react";
    
    const CustomTextField = lazy(() =>
      import("@design-system/shared/ui/").then((module) => ({ default: module.CustomTextField })),
    );
    
    export const StyledSelectField = styled(CustomTextField)(() => ({
      "& .MuiInputBase-input ": {
        lineHeight: "inherit",
      },
    }));

    코드 설명

    1. lazy() 함수: React의 lazy() 함수는 동적으로 컴포넌트를 불러올 수 있게 해줍니다. 이는 코드 분할(code splitting)을 가능하게 하여, 필요한 시점에 컴포넌트를 로드할 수 있습니다.
    2. 동적 import(): import() 함수를 사용하여 CustomTextField 컴포넌트를 동적으로 불러옵니다. 이 방식은 모듈을 비동기적으로 로드하여 순환 참조 문제를 해결합니다.
    3. then() 메서드: 동적 import가 완료된 후, then() 메서드를 통해 모듈에서 CustomTextField 컴포넌트를 추출합니다.
    4. styled() 함수: MUI의 styled() 함수를 사용하여 동적으로 불러온 CustomTextField에 추가적인 스타일을 적용합니다.

    이 접근 방식은 CustomTextField의 로딩을 지연시켜 순환 참조 문제를 해결합니다. StyledSelectField가 정의될 때 CustomTextField의 실제 구현은 아직 로드되지 않았기 때문에, JavaScript 엔진은 순환 참조를 감지하지 않습니다.

    순환 참조 해결을 위한 다른 방법들

    1. 모듈 구조 재설계: 컴포넌트 간의 의존성을 재검토하고, 가능하다면 구조를 변경하여 순환 참조를 제거합니다.
    2. 공통 기본 컴포넌트 생성: 여러 컴포넌트가 공유하는 기본 스타일과 기능을 가진 새로운 컴포넌트를 만들어 사용합니다.
    3. HOC(Higher-Order Component) 패턴 사용: 스타일을 적용하는 HOC를 만들어 여러 컴포넌트에 재사용합니다.
    4. Context API 활용: 공통 스타일이나 속성을 Context를 통해 제공하여 직접적인 import를 줄입니다.
    5. 스타일 분리: 스타일을 별도의 파일로 분리하여 컴포넌트 간 직접적인 의존성을 줄입니다.

    결론

    순환 참조는 React 애플리케이션 개발 시 자주 마주치는 문제 중 하나입니다. lazy()와 동적 import()를 활용한 해결 방법은 코드의 구조를 크게 변경하지 않으면서도 효과적으로 문제를 해결할 수 있는 방법입니다.

    이 방법은 특히 대규모 프로젝트에서 유용하며, 코드 분할의 이점도 함께 얻을 수 있습니다. 그러나 상황에 따라 다른 해결 방법들도 고려해 볼 수 있으며, 프로젝트의 구조와 요구사항에 가장 적합한 방법을 선택하는 것이 중요합니다.

    순환 참조 문제에 직면했을 때, 이러한 다양한 해결 방법들을 고려하여 가장 적절한 방법을 선택하면, 더 견고하고 유지보수가 용이한 React 애플리케이션을 개발할 수 있을 것입니다.

    반응형

    댓글

Luster Sun