React 인터뷰 질문 및 답변

ReactBeginner
지금 연습하기

소개

React 인터뷰 질문 및 답변에 대한 종합 가이드에 오신 것을 환영합니다! React 개발 환경을 탐색하려면 핵심 원칙과 실제 적용에 대한 탄탄한 이해가 필요합니다. 이 문서는 다음 React 인터뷰에서 탁월한 성과를 거두는 데 필요한 지식과 자신감을 갖추도록 세심하게 제작되었습니다. 기본 개념과 고급 패턴부터 테스트, 도구 및 문제 해결에 이르기까지 광범위한 주제를 다루어 이론적 및 실제적 과제 모두에 대비할 수 있도록 합니다. 신진 개발자이든 숙련된 전문가이든 이 자료는 React 를 마스터하고 꿈의 직업을 확보하는 데 필수적인 동반자가 될 것입니다.

REACT

기본 React 개념

React 란 무엇이며 주요 기능은 무엇인가요?

답변:

React 는 사용자 인터페이스, 특히 단일 페이지 애플리케이션을 구축하기 위한 JavaScript 라이브러리입니다. 주요 기능으로는 선언적 패러다임, 컴포넌트 기반 아키텍처, 효율적인 업데이트를 위한 가상 DOM(Virtual DOM) 사용 등이 있습니다.


React 에서 가상 DOM(Virtual DOM) 개념을 설명해주세요.

답변:

가상 DOM 은 실제 DOM 의 경량 복사본입니다. 상태가 변경되면 React 는 먼저 가상 DOM 을 업데이트한 다음, diffing 알고리즘을 사용하여 실제 DOM 에 필요한 최소한의 변경 사항을 효율적으로 계산하고, 마지막으로 해당 특정 부분만 업데이트합니다.


JSX 란 무엇이며 React 에서 왜 사용되나요?

답변:

JSX(JavaScript XML) 는 JavaScript 내에서 HTML 과 유사한 코드를 직접 작성할 수 있게 해주는 JavaScript 의 구문 확장입니다. React 에서는 UI 가 어떻게 보여야 하는지를 설명하는 데 사용되며, 컴포넌트 구조와 렌더링 로직을 더 직관적이고 읽기 쉽게 만듭니다.


React 에서 함수형 컴포넌트와 클래스 컴포넌트를 구분해주세요.

답변:

함수형 컴포넌트는 JSX 를 반환하는 일반 JavaScript 함수로, 일반적으로 표현 컴포넌트에 사용됩니다. 클래스 컴포넌트는 React.Component를 확장하는 ES6 클래스로, 자체 상태 (state) 와 생명주기 메서드 (lifecycle methods) 를 가집니다. React Hooks 를 사용하면 함수형 컴포넌트도 이제 상태와 부수 효과 (side effects) 를 관리할 수 있습니다.


React 에서 Props 란 무엇인가요?

답변:

Props(properties 의 줄임말) 는 부모 컴포넌트에서 자식 컴포넌트로 데이터를 전달하는 메커니즘입니다. Props 는 읽기 전용이며 단방향 데이터 흐름을 유지하는 데 도움이 되어, 자식 컴포넌트가 자신에게 전달된 데이터를 직접 수정할 수 없도록 합니다.


React 에서 State 개념을 설명해주세요.

답변:

State 는 컴포넌트 내에서 시간이 지남에 따라 변경될 수 있는 데이터를 보유하는 객체입니다. State 는 컴포넌트에 비공개이며 해당 컴포넌트의 동작과 렌더링을 제어합니다. State 가 변경되면 React 는 해당 컴포넌트와 그 자식 컴포넌트들을 다시 렌더링합니다.


React Hooks 란 무엇이며 왜 도입되었나요?

답변:

React Hooks 는 함수형 컴포넌트에서 React 상태 및 생명주기 기능에 '연결 (hook into)'할 수 있게 해주는 함수입니다. Hooks 는 함수형 컴포넌트가 상태와 부수 효과를 관리할 수 있도록 도입되었으며, 개발자가 함수만으로 컴포넌트를 작성할 수 있게 하여 코드 재사용성과 가독성을 향상시킵니다.


useStateuseEffect Hooks 의 목적은 무엇인가요?

답변:

useState는 함수형 컴포넌트에 React 상태를 추가할 수 있게 해주는 Hook 으로, 상태 값과 이를 업데이트하는 함수를 반환합니다. useEffect는 모든 렌더링 후에 함수형 컴포넌트에서 부수 효과 (데이터 가져오기, 구독, DOM 수동 변경 등) 를 수행할 수 있게 해주는 Hook 입니다.


React 에서 목록을 렌더링할 때 Keys 의 중요성은 무엇인가요?

답변:

Keys 는 요소 목록을 생성할 때 포함해야 하는 특별한 문자열 속성입니다. Keys 는 React 가 어떤 항목이 변경되었는지, 추가되었는지 또는 제거되었는지를 식별하는 데 도움을 주어, React 가 UI 를 효율적으로 업데이트하고 재렌더링 시 컴포넌트의 동일성을 유지함으로써 잠재적인 버그를 방지할 수 있도록 합니다.


React Hooks 및 상태 관리

React Hooks 란 무엇이며 왜 도입되었나요?

답변:

React Hooks 는 함수형 컴포넌트에서 React 상태 및 생명주기 기능에 '연결 (hook into)'할 수 있게 해주는 함수입니다. Hooks 는 개발자가 클래스 컴포넌트를 작성하지 않고도 상태 및 기타 React 기능을 사용할 수 있도록 도입되었으며, 코드 재사용성, 가독성 향상, '래퍼 지옥 (wrapper hell)' 및 복잡한 생명주기 메서드와 같은 문제 해결을 촉진합니다.


useState Hook 의 목적을 설명해주세요.

답변:

useState Hook 은 함수형 컴포넌트가 상태를 관리할 수 있도록 합니다. 상태 값과 이를 업데이트하는 함수를 반환합니다. setter 함수가 호출되면 React 는 새로운 상태 값으로 컴포넌트를 다시 렌더링합니다.


useEffect Hook 은 어떻게 작동하며 일반적인 사용 사례는 무엇인가요?

답변:

useEffect Hook 은 함수형 컴포넌트에서 데이터 가져오기, 구독 설정 또는 DOM 수동 변경과 같은 부수 효과 (side effects) 를 수행할 수 있도록 합니다. 기본적으로 모든 렌더링 후에 실행되지만, 의존성 배열 (dependency array) 을 지정하여 실행을 제어할 수 있습니다. 일반적인 사용 사례로는 컴포넌트 마운트 시 데이터 가져오기, 이벤트 리스너 설정 및 리소스 정리 등이 있습니다.


useEffect에서 의존성 배열 (dependency array) 의 중요성은 무엇인가요?

답변:

useEffect의 의존성 배열은 효과 (effect) 가 언제 다시 실행될지를 제어합니다. 배열이 비어 있으면 ([]), 효과는 초기 렌더링 후에 한 번만 실행됩니다. 생략하면 모든 렌더링 후에 실행됩니다. 값이 포함되어 있으면, 해당 값 중 하나가 변경될 때만 효과가 다시 실행되어 불필요한 재실행 및 잠재적인 무한 루프를 방지합니다.


useContext는 언제 사용해야 하나요?

답변:

useContext는 React Context 에서 값을 가져오는 데 사용됩니다. 각 레벨에서 수동으로 props 를 전달하지 않고도 컴포넌트 트리를 통해 데이터를 깊숙이 전달할 수 있는 방법을 제공하여 'prop drilling'을 피할 수 있게 합니다. 테마, 사용자 인증 또는 로케일과 같은 전역 상태에 이상적입니다.


useStateuseReducer의 차이점을 설명해주세요.

답변:

useState는 일반적으로 기본값 (primitive values) 또는 작은 객체를 위한 간단한 상태 관리에 사용됩니다. useReducer는 더 복잡한 상태 로직, 특히 상태 전환이 여러 하위 값을 포함하거나 다음 상태가 이전 상태에 의존하는 경우에 useState의 대안입니다. 애플리케이션 전체 상태를 관리하거나 상태 업데이트가 복잡하고 'reducer' 함수를 포함하는 경우에 자주 사용됩니다.


useCallback이란 무엇이며 언제 사용해야 하나요?

답변:

useCallback은 메모이제이션된 (memoized) 콜백 함수를 반환하는 Hook 입니다. 특히 부모 컴포넌트에서 전달된 콜백에 의존하는 자식 컴포넌트의 불필요한 리렌더링을 방지하는 데 사용됩니다. 참조 동등성 (referential equality) 을 유지하기 위해 최적화된 자식 컴포넌트 (예: React.memo) 에 콜백을 전달할 때 유용합니다.


useMemo란 무엇이며 useCallback과 어떻게 다른가요?

답변:

useMemo는 메모이제이션된 값을 반환하는 Hook 입니다. 의존성이 변경되지 않은 경우 비용이 많이 드는 계산이 렌더링 시마다 다시 실행되는 것을 방지하여 성능을 최적화하는 데 사용됩니다. useCallback이 함수를 메모이제이션하는 반면, useMemo는 함수 호출의 결과 (값) 를 메모이제이션합니다.


'Hooks 규칙'을 설명해주세요.

답변:

두 가지 주요 규칙이 있습니다: 1) Hooks 는 React 함수형 컴포넌트 또는 사용자 정의 Hooks 의 최상위 레벨에서만 호출해야 합니다. 루프, 조건문 또는 중첩 함수 내에서는 호출하지 마세요. 2) Hooks 는 React 함수형 컴포넌트 또는 사용자 정의 Hooks 에서만 호출해야 합니다. 일반 JavaScript 함수에서는 호출하지 마세요. 이러한 규칙은 모든 렌더링에서 Hooks 가 동일한 순서로 호출되도록 보장합니다.


사용자 정의 Hooks 는 어떻게 작동하며 어떤 이점이 있나요?

답변:

사용자 정의 Hooks 는 이름이 use로 시작하고 다른 Hooks 를 호출할 수 있는 JavaScript 함수입니다. 이를 통해 컴포넌트에서 재사용 가능한 상태 로직을 추출할 수 있어, prop drilling 이나 render props 없이도 다른 컴포넌트 간에 로직을 쉽게 공유할 수 있습니다. 이점으로는 코드 구성, 재사용성 및 테스트 용이성 향상이 있습니다.


React 의 내장 Hooks 인 useStateuseContext 대신 전역 상태 관리 라이브러리 (예: Redux, Zustand) 를 선택하는 경우는 언제인가요?

답변:

소규모 및 중간 규모 애플리케이션의 경우 useStateuseContext로도 충분한 경우가 많습니다. 그러나 복잡한 상태 상호 작용, 빈번한 업데이트 또는 중앙 집중식 디버깅 도구 (예: Redux DevTools) 가 필요한 대규모 애플리케이션의 경우, 전용 전역 상태 관리 라이브러리가 더 나은 확장성, 예측 가능성 및 유지 관리성을 제공합니다. 이러한 라이브러리는 미들웨어, 불변성 강제 및 단일 진실 공급원 (single source of truth) 과 같은 기능을 제공합니다.


useRef의 목적은 무엇인가요?

답변:

useRef.current 속성이 전달된 인수로 초기화된 변경 가능한 ref 객체를 반환합니다. 반환된 객체는 컴포넌트의 전체 수명 주기 동안 지속됩니다. 일반적으로 DOM 요소에 직접 액세스하고 상호 작용하거나, 업데이트 시 리렌더링을 유발하지 않는 변경 가능한 값 (예: 타이머 ID) 을 저장하는 데 사용됩니다.


고급 React 패턴 및 성능 최적화

React.memo의 목적과 사용 시점을 설명해주세요.

답변:

React.memo는 함수형 컴포넌트를 메모이제이션 (memoize) 하여 props 가 변경되지 않은 경우 리렌더링을 방지하는 고차 컴포넌트 (HOC) 입니다. 동일한 props 로 자주 리렌더링되는 컴포넌트, 특히 계산 비용이 많이 드는 컴포넌트의 성능을 최적화하는 데 유용합니다.


useCallback Hook 이란 무엇이며 성능에 어떻게 도움이 되나요?

답변:

useCallback은 함수를 메모이제이션하여, 의존성 중 하나가 변경된 경우에만 변경되는 메모이제이션된 콜백 버전을 반환합니다. 이는 props 에 대한 참조 동등성 (referential equality) 에 의존하는 자식 컴포넌트의 불필요한 리렌더링을 방지합니다 (예: React.memo와 함께 사용할 때).


useMemo는 언제 사용하며 어떤 문제를 해결하나요?

답변:

useMemo는 값을 메모이제이션하여, 의존성 중 하나가 변경될 때만 다시 계산합니다. 이는 모든 렌더링 시 비용이 많이 드는 계산을 피하는 데 사용되며, 복잡한 로직이나 객체/배열 생성을 불필요하게 다시 실행하는 것을 방지하여 성능을 향상시킵니다.


React 에서 '상태 끌어올리기 (lifting state up)' 개념과 그 이점을 설명해주세요.

답변:

'상태 끌어올리기'는 공유 상태를 가장 가까운 공통 조상 컴포넌트로 이동시키는 것을 포함합니다. 이는 상태 관리를 중앙 집중화하고, 데이터 흐름을 단순화하며, 해당 상태가 필요한 모든 컴포넌트가 단일 진실 공급원 (single source of truth) 에 접근할 수 있도록 보장하여 디버깅을 용이하게 합니다.


Context API 란 무엇이며 prop drilling 대신 언제 좋은 선택인가요?

답변:

Context API 는 모든 레벨에서 수동으로 props 를 전달할 필요 없이 (prop drilling) 컴포넌트 트리를 통해 데이터를 전달하는 방법을 제공합니다. 테마, 사용자 인증 또는 로케일과 같은 전역 데이터에 이상적이며, 깊숙이 중첩된 컴포넌트에 대한 번거로운 prop 전달을 피할 수 있습니다.


'render props' 개념을 설명하고 간단한 사용 사례를 제공해주세요.

답변:

'render props' 패턴은 컴포넌트가 자식에게 prop 으로 함수를 전달하고, 자식이 해당 함수를 호출하여 콘텐츠를 렌더링하는 것을 포함합니다. 이는 상태 로직이나 동작을 재사용해야 하는 컴포넌트 간에 코드를 공유하는 데 사용됩니다. 예를 들어, MouseTracker 컴포넌트가 마우스 좌표를 자식에게 전달하는 경우입니다.


고차 컴포넌트 (HOC) 란 무엇이며 render props 와 어떻게 다른가요?

답변:

HOC 는 컴포넌트를 받아 향상된 props 또는 동작을 가진 새 컴포넌트를 반환하는 함수입니다. HOC 는 컴포넌트를 래핑하여 props 를 주입하는 반면, render props 는 렌더링을 위해 함수를 prop 으로 전달하여 코드 재사용을 달성하는 다른 방법을 제공한다는 점에서 render props 와 다릅니다.


React 에서 대규모 목록을 다룰 때 성능을 어떻게 최적화할 수 있나요?

답변:

대규모 목록의 경우 가상화 또는 윈도잉 (windowing) 라이브러리 (예: react-window, react-virtualized) 를 사용하세요. 이러한 라이브러리는 뷰포트에서 보이는 항목만 렌더링하여 DOM 노드 수를 크게 줄이고 렌더링 성능 및 메모리 사용량을 개선합니다.


코드 분할 (code splitting) 이란 무엇이며 React 애플리케이션 성능을 어떻게 향상시킬 수 있나요?

답변:

코드 분할은 애플리케이션의 번들을 더 작은 청크로 나누어 필요에 따라 로드하는 기술입니다. 초기 로드 시간을 줄여 성능을 향상시키는데, 사용자는 현재 보기에 필요한 코드만 다운로드하므로 더 빠른 로딩 속도를 경험할 수 있습니다.


React.lazySuspense의 목적을 설명해주세요.

답변:

React.lazy를 사용하면 동적 임포트 (dynamic import) 를 일반 컴포넌트처럼 렌더링할 수 있어 컴포넌트 수준에서 코드 분할이 가능합니다. SuspenseReact.lazy 컴포넌트가 로드될 때까지 '대기'하는 데 사용되며, 컴포넌트가 준비될 때까지 대체 UI(예: 스피너) 를 표시합니다.


시나리오 기반 문제 해결

표시해야 할 항목이 많은 목록 (예: 1000 개 이상의 행) 이 있습니다. UI 가 멈추는 것을 방지하기 위해 렌더링 성능을 어떻게 최적화하시겠습니까?

답변:

'가상 스크롤링 (virtualized scrolling)' 또는 '윈도잉 (windowing)'을 구현하겠습니다. react-window 또는 react-virtualized와 같은 라이브러리는 뷰포트에서 보이는 항목만 렌더링하여 DOM 노드 수를 크게 줄이고 대규모 목록의 성능을 향상시킵니다.


해당 변경 사항이 시각적 출력에 영향을 미치지 않더라도 props 변경으로 인해 컴포넌트가 자주 리렌더링됩니다. 불필요한 리렌더링을 방지하려면 어떻게 해야 합니까?

답변:

함수형 컴포넌트에는 React.memo를, 클래스 컴포넌트에는 PureComponent를 사용하겠습니다. 이들은 props 와 state 를 얕은 비교 (shallow comparison) 하여 실제로 변경되지 않은 경우 리렌더링을 방지합니다. 대안으로, useCallbackuseMemo를 사용하여 props 로 전달되는 함수와 값을 메모이제이션할 수 있습니다.


컴포넌트가 마운트될 때 API 에서 데이터를 가져와 로딩 상태를 표시해야 합니다. 오류 처리를 포함하여 이를 어떻게 처리하시겠습니까?

답변:

마운트 시 데이터를 가져오기 위해 빈 의존성 배열 ([]) 과 함께 useEffect Hook 을 사용하겠습니다. loading, data, error 상태를 관리하기 위해 상태 변수를 사용하겠습니다. useEffect 내의 try-catch 블록은 API 오류를 처리하고 해당 오류에 따라 error 상태를 설정합니다.


useState 대신 useRef를 사용하는 시나리오를 설명해주세요.

답변:

useRef는 DOM 요소에 직접 액세스 (예: 입력 필드 포커스), 리렌더링을 트리거하지 않는 변경 가능한 값 저장 (예: 타이머 ID), 또는 자식 컴포넌트 인스턴스에 대한 참조를 보유하는 데 이상적입니다. useState는 리렌더링을 유발해야 하는 상태를 관리하는 데 사용됩니다.


컴포넌트 트리가 깊게 중첩되어 있고, 자식 컴포넌트가 멀리 떨어진 조상 컴포넌트의 상태를 업데이트해야 합니다. prop drilling 없이 이 상태 업데이트를 어떻게 관리하시겠습니까?

답변:

React Context API 를 사용하겠습니다. 조상 컴포넌트는 Context Provider 를 통해 상태와 업데이트 함수를 제공하고, 멀리 떨어진 자식 컴포넌트는 useContext를 사용하여 이를 소비하여 중간 컴포넌트를 통한 prop drilling 을 피합니다.


사용자가 여러 페이지를 탐색한 후 React 애플리케이션이 느리다고 보고합니다. 성능을 디버깅하고 최적화하기 위해 어떤 단계를 취하시겠습니까?

답변:

React DevTools Profiler 를 사용하여 리렌더링 병목 현상을 식별하는 것부터 시작하겠습니다. 그런 다음 React.memo, useCallback, useMemo를 사용하여 불필요한 리렌더링을 확인하고 데이터 가져오기를 최적화할 것입니다. React.lazySuspense를 사용한 코드 분할도 초기 로드 시간을 개선할 수 있습니다.


애플리케이션의 어느 곳에서든 트리거할 수 있는 전역 모달 컴포넌트를 어떻게 구현하시겠습니까?

답변:

React Portals 를 사용하여 모달을 컴포넌트의 DOM 계층 구조 외부, 일반적으로 document.body 바로 아래에 렌더링하겠습니다. Context API 또는 전역 상태 관리 라이브러리 (예: Redux/Zustand)를 사용하여 모달의 열기/닫기 상태와 콘텐츠를 관리하여 모든 컴포넌트에서 트리거할 수 있도록 합니다.


React 애플리케이션에 폼 유효성 검사를 구현해야 합니다. 어떤 접근 방식을 취하시겠습니까?

답변:

폼 입력 값과 유효성 검사 오류를 컴포넌트 상태로 관리하겠습니다. 입력 변경 시 값을 업데이트합니다. 폼 제출 시 유효성 검사 검사를 수행하고, 유효하지 않으면 상태에 오류 메시지를 설정합니다. Formik 또는 React Hook Form 과 같은 라이브러리를 사용하면 이 프로세스를 크게 간소화할 수 있습니다.


사용자가 항목을 드래그 앤 드롭할 수 있는 기능을 구축하고 있습니다. React 에서 이를 구현하려면 어떻게 접근하시겠습니까?

답변:

HTML Drag and Drop API 이벤트 (onDragStart, onDragOver, onDrop) 를 사용하여 드래그 상태와 대상을 관리하겠습니다. 또는 더 복잡한 상호 작용을 위해 react-beautiful-dnd 또는 react-dnd와 같은 전용 라이브러리를 활용하여 복잡성을 많이 추상화하고 더 나은 접근성을 제공할 수 있습니다.


React Router 애플리케이션에서 인증 및 보호된 라우트를 어떻게 처리하시겠습니까?

답변:

사용자가 인증되었는지 (예: 로컬 스토리지 또는 컨텍스트의 토큰을 통해) 확인하는 ProtectedRoute 컴포넌트를 사용하겠습니다. 인증된 경우 요청된 컴포넌트를 렌더링하고, 그렇지 않으면 react-router-domNavigate를 사용하여 사용자를 로그인 페이지로 리디렉션합니다.


React 생태계 및 도구

React 프로젝트에서 Webpack 과 같은 빌드 도구의 목적은 무엇인가요?

답변:

Webpack 은 프로젝트의 모든 애셋 (JavaScript, CSS, 이미지 등) 을 가져와 배포를 위해 몇 개의 최적화된 파일로 번들링하는 모듈 번들러입니다. 트랜스파일링 (Babel), 최소화 (minification), 코드 분할과 같은 작업을 처리하여 브라우저에서 애플리케이션을 효율적이고 성능 좋게 만듭니다.


React 개발 워크플로우에서 Babel 의 역할을 설명해주세요.

답변:

Babel 은 최신 JavaScript(ES6+, JSX) 를 이전 브라우저에서 이해할 수 있는 호환 가능한 JavaScript 버전으로 트랜스파일하는 JavaScript 컴파일러입니다. 이를 통해 개발자는 최신 언어 기능과 JSX 구문을 사용하면서도 React 애플리케이션에 대한 광범위한 브라우저 호환성을 보장할 수 있습니다.


React 생태계에서 일반적으로 사용되는 테스트 라이브러리에는 어떤 것들이 있나요?

답변:

일반적인 테스트 라이브러리에는 단위 및 통합 테스트를 위한 Jest 와 사용자 상호 작용을 모방하는 방식으로 React 컴포넌트를 테스트하기 위한 React Testing Library 가 있습니다. Enzyme 도 인기 있는 선택지이지만, 접근성 및 사용자 중심 테스트에 중점을 둔 React Testing Library 가 종종 선호됩니다.


Create React App (CRA) 은 React 개발을 어떻게 단순화하나요?

답변:

CRA 는 Webpack 및 Babel 과 같은 복잡한 빌드 구성을 추상화하여 사전 구성된 개발 환경을 제공합니다. 개발, 테스트 및 빌드를 위한 필수 스크립트와 함께 즉시 사용 가능한 프로젝트 구조를 설정하여 개발자가 애플리케이션 코드 작성에 즉시 집중할 수 있도록 합니다.


Linter 란 무엇이며, React 프로젝트에서 ESLint 가 일반적으로 사용되는 이유는 무엇인가요?

답변:

Linter 는 코드를 실행하지 않고 잠재적인 오류, 스타일 문제 및 모범 사례 위반을 분석하는 도구입니다. ESLint 는 React 프로젝트에서 일관된 코드 스타일을 적용하고, 일반적인 프로그래밍 실수를 포착하며, 인기 있는 React 관련 규칙 세트 (예: eslint-plugin-react, eslint-plugin-jsx-a11y) 와 통합하는 데 널리 사용됩니다.


React 프로젝트에서 npm 또는 Yarn 과 같은 패키지 관리자의 목적을 설명해주세요.

답변:

npm(Node Package Manager) 및 Yarn 과 같은 패키지 관리자는 프로젝트 종속성을 관리하는 데 사용됩니다. 이를 통해 개발자는 프로젝트에 필요한 타사 라이브러리 및 도구를 설치, 업데이트 및 제거할 수 있으며, 개발 환경 전반에 걸쳐 일관된 종속성 버전을 보장합니다.


React 애플리케이션에서 컴포넌트 라이브러리 (예: Material-UI, Ant Design) 를 사용하는 이점은 무엇인가요?

답변:

컴포넌트 라이브러리는 미리 구축되고 재사용 가능한 UI 컴포넌트를 제공하며, 종종 스타일이 지정되고 즉시 사용 가능한 접근성을 갖추고 있습니다. 일반적인 UI 요소를 처음부터 구축할 필요성을 줄여 개발을 가속화하고, 디자인 일관성을 보장하며, 종종 접근성 및 반응형 디자인에 대한 모범 사례를 따릅니다.


개발 서버 (예: Webpack Dev Server) 는 React 개발 경험을 어떻게 향상시키나요?

답변:

개발 서버는 핫 모듈 교체 (HMR) 및 라이브 리로딩과 같은 기능을 제공하여 코드 변경 시 전체 페이지를 다시 로드하지 않고도 브라우저를 자동으로 새로 고치거나 모듈을 업데이트합니다. 이는 개발 피드백 루프를 크게 가속화하여 개발 프로세스를 더 효율적이고 즐겁게 만듭니다.


대규모 React 애플리케이션에서 Redux 또는 Zustand 와 같은 상태 관리 라이브러리의 역할은 무엇인가요?

답변:

상태 관리 라이브러리는 특히 대규모 애플리케이션에서 여러 컴포넌트에 걸쳐 공유해야 하는 복잡한 애플리케이션 상태를 관리하는 데 도움이 됩니다. 중앙 집중식 스토어와 예측 가능한 상태 업데이트 패턴을 제공하여 애플리케이션을 디버깅, 유지 관리 및 확장하기 쉽게 만듭니다.


React 프로젝트에 Create React App 대신 Next.js 또는 Remix 를 선택하는 경우는 언제인가요?

답변:

Next.js 와 Remix 는 서버 측 렌더링 (SSR), 정적 사이트 생성 (SSG) 및 API 라우트와 같은 기능을 기본적으로 제공하는 풀스택 React 프레임워크입니다. 더 나은 SEO, 더 빠른 초기 페이지 로드 또는 통합 백엔드 기능이 필요한 프로젝트에 대해 이를 선택할 수 있으며, 이는 CRA 가 기본적으로 제공하지 않는 기능입니다.


React 애플리케이션 테스트

React 애플리케이션에서 일반적으로 수행하는 주요 테스트 유형은 무엇인가요?

답변:

주요 유형에는 단위 테스트 (개별 컴포넌트/함수), 통합 테스트 (컴포넌트가 함께 작동하는 방식), 그리고 엔드투엔드 (E2E) 테스트 (전체 애플리케이션에 걸친 사용자 흐름 시뮬레이션) 가 있습니다. UI 회귀 테스트를 위한 스냅샷 테스트도 일반적입니다.


React 에서 단위 테스트의 목적은 무엇이며, 이를 위해 일반적으로 어떤 도구를 사용하나요?

답변:

단위 테스트는 개별 React 컴포넌트 또는 순수 함수를 격리하여 검증합니다. 컴포넌트가 올바르게 렌더링되고, props 를 처리하며, 예상대로 state 를 관리하는지 확인합니다. 일반적인 도구로는 테스트 러너로 Jest, DOM 상호 작용을 위해 React Testing Library 가 있습니다.


React 테스트에서 얕은 렌더링 (shallow rendering) 과 전체 DOM 렌더링 (full DOM rendering) 의 차이점을 설명해주세요.

답변:

얕은 렌더링 (예: Enzyme 의 shallow()) 은 테스트 대상 컴포넌트만 격리하여 자식 컴포넌트 없이 컴포넌트 자체만 렌더링합니다. 전체 DOM 렌더링 (예: React Testing Library 또는 Enzyme 의 mount()) 은 컴포넌트와 모든 자식 컴포넌트를 렌더링하여 브라우저 환경을 더 가깝게 시뮬레이션합니다.


React Testing Library 는 무엇이며, 새로운 프로젝트에서 Enzyme 보다 선호되는 이유는 무엇인가요?

답변:

React Testing Library(RTL) 는 React 컴포넌트를 테스트하기 위한 유틸리티 세트입니다. 컴포넌트의 내부 구현 세부 정보보다는 접근성 및 사용자 중심 쿼리에 중점을 두어 사용자가 상호 작용하는 방식으로 컴포넌트를 테스트하도록 권장합니다. 이를 통해 더 강력하고 유지 관리하기 쉬운 테스트를 작성할 수 있습니다.


React Testing Library 에서 클릭 또는 입력 변경과 같은 사용자 상호 작용을 어떻게 시뮬레이션하나요?

답변:

@testing-library/reactfireEvent 또는 userEvent 유틸리티를 사용합니다. 예를 들어, fireEvent.click(screen.getByText('Submit'))은 클릭을 시뮬레이션하고, userEvent.type(screen.getByLabelText('Username'), 'test')는 입력 필드에 타이핑을 시뮬레이션합니다.


스냅샷 테스트는 무엇이며, React 에서 언제 사용해야 하나요?

답변:

스냅샷 테스트는 컴포넌트의 렌더링 출력 (또는 직렬화 가능한 모든 값) 의 직렬화된 표현을 캡처하고 이전에 저장된 스냅샷과 비교합니다. 의도하지 않은 UI 변경 또는 회귀를 감지하는 데 유용하며, 특히 프레젠테이션 컴포넌트에 유용합니다.


React 컴포넌트에서 비동기 작업 (예: 데이터 가져오기) 을 어떻게 테스트하나요?

답변:

jest-fetch-mock 또는 msw(Mock Service Worker) 와 같은 라이브러리를 사용하여 API 호출을 모킹할 수 있습니다. 그런 다음 React Testing Library 의 waitFor 또는 findBy 쿼리와 함께 async/await를 사용하여 비동기 작업이 완료된 후 DOM 에 요소가 나타날 때까지 기다립니다.


React 애플리케이션에 Cypress 또는 Playwright 와 같은 엔드투엔드 (E2E) 테스트 프레임워크를 사용하는 경우는 언제인가요?

답변:

E2E 테스트는 백엔드 상호 작용 및 데이터베이스 작업을 포함하여 애플리케이션 전체의 사용자 흐름을 검증하는 데 사용되며, 실제 사용자의 여정을 시뮬레이션합니다. 배포된 환경에서 중요한 경로가 올바르게 작동하는지 확인하는 데 중요합니다.


Jest 에서 React 컴포넌트 테스트를 위해 모듈 또는 함수를 어떻게 모킹하나요?

답변:

Jest 는 전체 모듈을 모킹하기 위해 jest.mock()을, 모듈 또는 객체 내의 특정 함수를 모킹하기 위해 jest.spyOn()을 제공합니다. 이를 통해 종속성의 동작을 제어하고 테스트 대상 컴포넌트를 격리할 수 있습니다.


React Testing Library 에서 screen 객체의 역할은 무엇인가요?

답변:

screen 객체는 전체 문서 본문을 검색하는 쿼리에 대한 액세스를 제공합니다. 이는 테스트를 더 읽기 쉽고 일관성 있게 만들기 위해 render 결과에서 추출하지 않고도 요소를 쿼리하는 것을 단순화하는 전역 객체입니다.


React 모범 사례 및 아키텍처

React Context API 의 목적은 무엇이며, prop drilling 대신 언제 사용해야 하나요?

답변:

React Context API 는 모든 레벨에서 수동으로 props 를 전달할 필요 없이 컴포넌트 트리를 통해 데이터를 전달하는 방법을 제공합니다. 테마, 사용자 인증 상태 또는 로케일과 같이 여러 중첩된 컴포넌트에서 prop drilling 이 번거롭고 장황해지는 전역 데이터에 사용하세요.


React 에서 '상태 끌어올리기 (lifting state up)' 개념을 설명해주세요. 언제 유익한가요?

답변:

상태 끌어올리기는 상태를 자식 컴포넌트에서 가장 가까운 공통 조상으로 이동시키는 것을 포함합니다. 이는 여러 컴포넌트가 동일한 상태를 공유하거나 해당 상태에 반응해야 할 때 유익하며, 단일 진실 공급원 (single source of truth) 을 보장하고 형제 컴포넌트 간의 데이터 흐름 또는 부모 - 자식 상호 작용을 단순화합니다.


React Hooks 는 무엇이며, 왜 도입되었나요?

답변:

React Hooks 는 함수 컴포넌트에서 React 상태 및 생명주기 기능에 '훅 (hook)'할 수 있게 해주는 함수입니다. 함수 컴포넌트에서 상태 기반 로직을 활성화하고, 코드 재사용을 촉진하며, wrapper hell 및 복잡한 클래스 컴포넌트 생명주기와 같은 문제를 해결하기 위해 도입되었습니다.


React 폼에서 제어 컴포넌트 (controlled components) 와 비제어 컴포넌트 (uncontrolled components) 의 차이점을 설명해주세요.

답변:

제어 컴포넌트는 폼 데이터를 React 상태로 처리하며, 이는 React 가 입력 값의 '단일 진실 공급원'임을 의미합니다. 비제어 컴포넌트는 DOM 이 폼 데이터를 처리하도록 하며, 일반적으로 필요할 때 현재 값을 얻기 위해 ref를 사용하여 기본적인 폼에 대한 더 간단한 접근 방식을 제공합니다.


useCallbackuseMemo 훅은 언제 사용하며, 어떤 문제를 해결하나요?

답변:

useCallback은 함수를 메모이제이션하여 props 로 콜백을 받는 자식 컴포넌트의 불필요한 리렌더링을 방지합니다. useMemo는 값을 메모이제이션하여 모든 렌더링 시 값비싼 재계산을 방지합니다. 둘 다 종속성이 변경되지 않았을 때 불필요한 계산이나 리렌더링을 방지하여 성능을 최적화합니다.


React 목록에서 key prop 의 중요성은 무엇인가요?

답변:

key prop 은 React 가 목록에서 어떤 항목이 변경되었는지, 추가되었는지 또는 제거되었는지를 식별하는 데 도움이 됩니다. 각 요소에 안정적인 식별자를 제공하여 React 가 DOM 을 효율적으로 업데이트하고 목록 항목의 순서가 변경되거나 변경될 때 컴포넌트 상태 또는 잘못된 렌더링과 관련된 잠재적인 문제를 방지할 수 있도록 합니다.


React 애플리케이션에서 성능을 어떻게 최적화하나요?

답변:

성능 최적화는 여러 기법을 포함합니다: 메모이제이션을 위한 React.memo, useCallback, useMemo 사용; React.lazySuspense를 사용한 컴포넌트 지연 로딩; 긴 목록의 가상화; 상태 업데이트 최적화; 그리고 병목 현상을 식별하기 위한 React DevTools 프로파일러 사용.


React 에서 서버 측 렌더링 (SSR) 개념을 설명해주세요. 이점은 무엇인가요?

답변:

SSR 은 클라이언트로 보내기 전에 서버에서 React 컴포넌트를 HTML 로 렌더링하는 것을 포함합니다. 이점으로는 초기 페이지 로드 성능 향상 (더 빠른 체감 로드 시간), 검색 엔진 크롤러가 콘텐츠를 쉽게 색인할 수 있어 SEO 개선, 그리고 더 접근 가능한 초기 렌더링이 있습니다.


React 에서 컴포넌트 합성은 무엇이며, 상속보다 선호되는 이유는 무엇인가요?

답변:

컴포넌트 합성은 더 간단하고 독립적인 컴포넌트를 결합하여 복잡한 UI 를 구축하는 것입니다. 이는 더 큰 유연성, 재사용성 및 유지 관리성을 제공하기 때문에 상속보다 선호됩니다. 컴포넌트는 props 를 통해 데이터와 동작을 전달할 수 있어 더 모듈화되고 예측 가능한 아키텍처를 촉진합니다.


React 의 내장 Context API 대신 Redux 또는 Zustand 와 같은 상태 관리 라이브러리 사용을 고려하는 경우는 언제인가요?

답변:

복잡한 상태 로직, 빈번한 업데이트 또는 예측 가능한 상태 변경 및 디버깅 도구 (시간 여행 디버깅과 같은) 가 필요한 대규모 애플리케이션의 경우 전용 상태 관리 라이브러리가 유익합니다. Context API 는 더 간단한 전역 상태 또는 덜 빈번한 업데이트에 적합합니다.


React 애플리케이션 문제 해결 및 디버깅

React 애플리케이션 디버깅에 주로 사용하는 도구는 무엇인가요?

답변:

주로 React Developer Tools(브라우저 확장 프로그램) 를 사용하여 컴포넌트 트리, props, state 및 성능을 검사합니다. 브라우저 개발자 도구 (콘솔, 네트워크, 디버거) 도 일반적인 JavaScript 디버깅, 네트워크 요청 및 오류 로깅에 필수적입니다.


props 또는 state 가 변경될 때 리렌더링되지 않는 컴포넌트를 어떻게 디버깅하나요?

답변:

먼저 shouldComponentUpdate(클래스 컴포넌트의 경우) 또는 React.memo(함수 컴포넌트의 경우) 가 잘못 구현되어 업데이트를 방지하고 있는지 확인합니다. 그런 다음 props 또는 state 가 실제로 변경되고 있는지 로깅하여 확인하고, 직접적인 변경은 리렌더링을 트리거하지 않으므로 불변성 (immutability) 이 유지되는지 확인합니다.


React Developer Tools 를 사용하여 컴포넌트 state 및 props 를 검사하는 방법을 설명해주세요.

답변:

React DevTools 에서 'Components' 탭을 선택합니다. 트리 보기에서 컴포넌트를 클릭하면 해당 컴포넌트의 현재 props 와 state 가 오른쪽 패널에 표시됩니다. 여기서 state/props를 직접 수정하여 다양한 시나리오를 테스트할 수도 있습니다.


React 에서 'undefined 의 속성을 읽을 수 없습니다 (Cannot read properties of undefined)' 오류의 일반적인 원인은 무엇이며, 어떻게 디버깅하나요?

답변:

이는 종종 undefined 또는 null인 객체의 속성에 액세스하려고 할 때 발생합니다. 오류 줄 바로 앞에서 변수를 로깅하여 값을 확인하거나, 선택적 체이닝 (?.) 또는 조건부 렌더링을 사용하여 잠재적으로 정의되지 않은 데이터를 안전하게 처리함으로써 디버깅합니다.


React 애플리케이션에서 성능 병목 현상을 어떻게 식별하고 해결하나요?

답변:

React Developer Tools 의 'Profiler' 탭을 사용하여 컴포넌트 렌더링 시간을 기록하고 비용이 많이 드는 리렌더링을 식별합니다. 일반적인 해결책으로는 불필요한 리렌더링을 방지하기 위한 React.memo, useCallback, useMemo 사용 및 긴 목록의 가상화가 있습니다.


useEffect 훅으로 인한 무한 루프를 어떻게 디버깅하는지 설명해주세요.

답변:

useEffect의 무한 루프는 일반적으로 효과 내의 상태 업데이트가 적절한 종속성 배열 없이 효과를 다시 트리거할 때 발생합니다. 종속성 배열을 확인하여 효과를 다시 실행해야 하는 값만 포함하거나, 조건 없이 상태 설정 함수가 호출되는지 확인합니다.


React 에서 오류 경계 (error boundaries) 의 목적은 무엇이며, 디버깅에 어떻게 도움이 되나요?

답변:

오류 경계는 자식 컴포넌트 트리 내의 JavaScript 오류를 잡아내고, 해당 오류를 로깅하며, 대체 UI 를 표시하는 React 컴포넌트입니다. 전체 애플리케이션이 충돌하는 것을 방지하여 오류를 일으키는 특정 컴포넌트를 격리하고 디버깅하기 쉽게 만듭니다.


Context API 가 소비자 (consumers) 를 올바르게 업데이트하지 못하는 문제에 대해 어떻게 디버깅하나요?

답변:

Context.Provider에 전달된 value prop 이 실제로 변경되고 있는지, 그리고 소비자가 useContext 또는 Context.Consumer를 올바르게 사용하고 있는지 확인합니다. 업데이트 시 value 객체 자체가 직접 변경되는 것이 아니라 새로운 객체가 생성되는지 확인합니다.


프로덕션 환경에서만 발생하는 버그를 발견했습니다. 어떻게 디버깅에 접근하나요?

답변:

먼저 프로덕션 로그에서 오류 메시지를 확인합니다. 가능하다면 소스 맵 (source maps) 을 사용하여 브라우저에서 난독화된 코드를 디버깅합니다. 그렇지 않다면, 프로덕션 환경을 로컬에서 정확하게 복제하려고 시도하거나, 프로덕션 빌드에 대상 로깅/원격 측정 (telemetry) 을 추가하여 더 많은 정보를 수집합니다.


디버깅 시 console.log와 React DevTools 를 언제 사용하나요?

답변:

console.log는 실행의 특정 지점, 특히 루프 또는 복잡한 로직 내에서 변수 값을 추적하는 데 유용합니다. React DevTools 는 컴포넌트 트리, props, state 및 성능을 검사하는 데 더 적합하며, React 관련 측면에 대한 더 구조화된 보기를 제공합니다.


요약

React 인터뷰 질문을 마스터하는 것은 여러분의 헌신과 생태계에 대한 이해를 증명하는 것입니다. 이 문서는 여러분의 기술을 효과적으로 설명할 수 있는 지식과 자신감을 갖추도록 돕는 것을 목표로 했습니다. 기억하세요, 준비는 단순히 답변을 암기하는 것이 아니라, 여러분의 기초적인 이해를 공고히 하고 문제 해결 능력을 보여주는 것입니다.

기술 환경은 끊임없이 진화하고 있으며, 지속적인 학습이 앞서 나가는 열쇠입니다. 새로운 도전을 받아들이고, 새로운 패턴을 탐색하며, 계속해서 구축해 나가세요. React 개발자로서의 여러분의 여정은 끊임없는 성장과 혁신의 과정입니다. 인터뷰에서 행운을 빌며, 여러분이 창조할 수 있는 것의 한계를 계속 넓혀나가세요!