React 미드레벨 종합 기술면접
새 면접Q. React 애플리케이션에서 불필요한 API 호출이 반복적으로 발생하는 문제를 발견했습니다. 컴포넌트가 리렌더링될 때마다 동일한 데이터를 다시 fetch하는 상황인데, 이를 해결하기 위한 전략들을 설명해주세요. 또한 React Query나 SWR 같은 데이터 페칭 라이브러리를 도입하면 어떤 이점이 있나요?
먼저 useEffect의 dependency array를 정확히 설정하여 필요한 경우에만 API를 호출하도록 해야 합니다. 데이터를 상위 컴포넌트로 lifting하거나, 캐싱 전략을 적용할 수 있습니다. React Query나 SWR은 자동 캐싱, 백그라운드 리페칭, 중복 제거, 낙관적 업데이트 등을 제공하여 수동으로 구현해야 할 복잡한 로직을 간소화합니다. 특히 stale-while-revalidate 패턴으로 UX와 데이터 신선도를 동시에 개선할 수 있습니다.
- • useEffect dependency array 최적화
- • 데이터 캐싱 및 상태 관리 전략
- • React Query/SWR의 자동 캐싱과 중복 요청 제거
- • stale-while-revalidate 패턴의 이해
React Query의 staleTime과 cacheTime의 차이는 무엇이며, 실무에서 각각 어떻게 설정하는 것이 좋을까요?
Q. Render Props 패턴과 Higher-Order Component(HOC) 패턴을 비교 설명하고, Hooks가 등장한 이후 이 두 패턴의 사용이 줄어든 이유는 무엇인가요? 그럼에도 불구하고 여전히 HOC나 Render Props를 사용하는 것이 적절한 경우가 있다면 언제인가요?
Render Props는 함수를 자식으로 전달하여 렌더링 로직을 공유하고, HOC는 컴포넌트를 감싸서 props를 주입하는 패턴입니다. 두 패턴 모두 로직 재사용을 위해 사용되지만, wrapper hell과 props drilling 문제가 발생할 수 있습니다. Hooks는 로직 재사용을 더 간결하게 해결하여 대부분의 경우 선호됩니다. 하지만 클래스 컴포넌트와의 호환성이 필요하거나, 외부 라이브러리 통합, 또는 컴포넌트 트리 구조 자체를 조작해야 하는 경우 HOC가 여전히 유용합니다.
- • Render Props와 HOC의 개념과 차이점
- • wrapper hell 및 복잡도 증가 문제
- • Hooks의 장점과 로직 재사용의 간결성
- • 레거시 코드 호환성 및 특수 상황에서의 HOC 활용
여러 개의 HOC를 조합할 때 발생할 수 있는 문제점과, compose 함수를 사용한 HOC 합성 패턴에 대해 설명해주세요.
Q. 프로덕션 환경에서 특정 사용자들이 간헐적으로 빈 화면(white screen)을 보고한다는 리포트를 받았습니다. React 애플리케이션에서 이러한 문제를 디버깅하고 해결하기 위해 어떤 접근 방법을 사용하시겠습니까? 모니터링과 로깅 관점에서도 설명해주세요.
먼저 Error Boundary를 구현하여 런타임 에러를 catch하고 fallback UI를 표시해야 합니다. Sentry나 LogRocket 같은 에러 모니터링 도구를 통합하여 실제 에러 스택과 사용자 세션을 추적합니다. 브라우저 콘솔 로그를 원격으로 수집하고, 번들 사이즈와 청크 로딩 실패 여부를 확인합니다. 특정 브라우저나 네트워크 환경에서만 발생하는지 파악하고, source map을 활용해 minified 코드의 원본 위치를 추적합니다. 또한 lazy loading된 컴포넌트의 로딩 실패에 대한 retry 로직을 추가합니다.
- • Error Boundary 구현 및 fallback UI
- • Sentry/LogRocket 같은 에러 모니터링 도구 활용
- • 청크 로딩 실패 및 네트워크 이슈 확인
- • source map을 통한 에러 추적 및 retry 로직
청크 로딩 실패 시 자동으로 재시도하는 로직을 구현한다면 어떤 방식으로 설계하시겠습니까?
Q. 코드 리뷰 중 동료가 모든 state를 하나의 거대한 객체로 관리하고, 일부 필드만 변경할 때도 전체 객체를 spread operator로 복사하는 코드를 발견했습니다. 이런 접근 방식의 문제점과 개선 방안을 제시해주세요. useReducer를 사용하는 것이 더 나은 경우는 언제인가요?
거대한 state 객체는 일부 필드만 변경되어도 전체 객체가 새로 생성되어 불필요한 리렌더링을 유발할 수 있습니다. state를 논리적으로 분리하여 독립적인 useState로 관리하거나, 연관된 값들만 그룹화해야 합니다. 복잡한 state 업데이트 로직이 있거나, 다음 state가 이전 state에 의존하는 경우, 또는 여러 하위 값을 포함하는 복잡한 객체일 때는 useReducer가 적합합니다. useReducer는 업데이트 로직을 컴포넌트 외부로 분리하여 테스트와 재사용이 용이합니다.
- • state 분리를 통한 리렌더링 최적화
- • 논리적 단위로 state 그룹화
- • useReducer의 적절한 사용 시점
- • 업데이트 로직의 분리 및 테스트 용이성
immer 라이브러리를 사용하여 불변성을 관리하는 것의 장단점은 무엇이며, 어떤 상황에서 도입을 고려하시겠습니까?
Q. 다국어 지원(i18n)이 필요한 대규모 React 애플리케이션을 설계한다고 가정합니다. 번역 파일 관리, 동적 언어 전환, SEO 최적화, 번들 사이즈 최적화를 모두 고려한 아키텍처를 제안해주세요. SSR/SSG 환경에서는 어떻게 달라지나요?
react-i18next나 next-i18next 같은 라이브러리를 사용하여 번역 리소스를 관리합니다. 번역 파일은 언어별로 분리하고 dynamic import로 필요한 언어만 로드하여 초기 번들 사이즈를 줄입니다. Context API로 현재 언어를 전역 관리하고, localStorage에 사용자 선호 언어를 저장합니다. SSR 환경에서는 Accept-Language 헤더나 URL 경로로 초기 언어를 결정하고, 서버에서 해당 언어의 번역을 미리 주입합니다. SEO를 위해 hreflang 태그를 추가하고, 각 언어별로 별도 URL 구조를 사용합니다. SSG에서는 빌드 타임에 모든 언어 버전을 생성합니다.
- • i18n 라이브러리 선택 및 번역 파일 동적 로딩
- • Context API 및 localStorage를 통한 언어 상태 관리
- • SSR 환경에서 서버 사이드 언어 감지 및 주입
- • SEO를 위한 hreflang 및 URL 구조 설계
- • SSG 빌드 타임 다국어 페이지 생성
번역 키가 누락되었거나 번역이 아직 준비되지 않은 경우를 처리하는 fallback 전략은 어떻게 설계하시겠습니까?
아직 댓글이 없습니다. 첫 번째 댓글을 남겨보세요!