패스잇

프론트엔드 개발

React 면접 질문

React 면접에서 가장 자주 나오는 핵심 주제 — Virtual DOM과 재조정(Reconciliation), Hooks의 동작 원리, 상태 관리와 리렌더링 최적화를 모범답안과 함께 정리했습니다. 단순 암기가 아니라 "왜 그렇게 동작하는지"를 설명할 수 있어야 실무 면접을 통과합니다.

총 21문제 · 기초 7 · 중급 7 · 심화 7 · 모범답안 포함

React 면접 질문 — 기초

Q1 기초

React의 Virtual DOM이란 무엇이며, 어떤 이점이 있나요?

힌트 · 실제 DOM 조작 비용과 비교해서 설명해보세요.

React의 Virtual DOM은 실제 DOM의 가벼운 사본이라고 생각하시면 됩니다. React는 데이터가 변경될 때마다 Virtual DOM을 업데이트하고, 이전 Virtual DOM과 현재 Virtual DOM…

전체 모범답안 펼치기

React의 Virtual DOM은 실제 DOM의 가벼운 사본이라고 생각하시면 됩니다. React는 데이터가 변경될 때마다 Virtual DOM을 업데이트하고, 이전 Virtual DOM과 현재 Virtual DOM을 비교(Diffing)하여 실제 DOM에 변경해야 할 부분만 찾아냅니다.

이 과정이 중요한 이유는 실제 DOM 조작은 브라우저 성능에 큰 영향을 미치기 때문입니다. Virtual DOM을 사용하면 불필요한 DOM 업데이트를 최소화하여 렌더링 성능을 크게 향상시킬 수 있습니다. 즉, React는 Virtual DOM을 통해 변경 사항을 일괄적으로 처리하여 실제 DOM에 반영하므로, 더 효율적인 UI 업데이트가 가능해집니다.

#Virtual DOM#Diffing 알고리즘#렌더링 최적화#DOM 조작 최소화#성능 향상

이 질문 단독 페이지 →

Q2 기초

React의 key prop이 필요한 이유와 index를 key로 사용하면 안 되는 이유를 설명해주세요.

힌트 · Reconciliation 알고리즘과 리스트 항목 식별을 생각해보세요.

React에서 key prop은 React가 어떤 항목을 변경, 추가 또는 삭제해야 하는지 식별하는 데 필요한 고유한 식별자입니다. React는 이 key를 사용하여 가상 DOM을 효율적으로 업데이트하고, 불필요한…

전체 모범답안 펼치기

React에서 key prop은 React가 어떤 항목을 변경, 추가 또는 삭제해야 하는지 식별하는 데 필요한 고유한 식별자입니다. React는 이 key를 사용하여 가상 DOM을 효율적으로 업데이트하고, 불필요한 렌더링을 최소화하여 성능을 최적화합니다.

index를 key로 사용하면 데이터가 변경될 때 문제가 발생할 수 있습니다. 예를 들어, 리스트의 중간에 항목이 추가되거나 삭제되면 index가 변경되어 React는 모든 항목을 새로 렌더링해야 한다고 판단할 수 있습니다. 이는 성능 저하를 일으키고, 특히 입력 필드와 같이 내부 상태를 가진 컴포넌트의 경우 예측 불가능한 UI 동작을 초래할 수 있습니다.

따라서 각 항목을 고유하게 식별할 수 있는 id나 고유한 문자열을 key로 사용하는 것이 좋습니다. 이렇게 하면 React는 변경된 항목만 정확하게 업데이트하여 효율적인 렌더링을 유지할 수 있습니다.

#고유성#렌더링 최적화#가상 DOM#불변성#예측 불가능한 UI

이 질문 단독 페이지 →

Q3 기초

React에서 JSX란 무엇이며, 브라우저가 직접 이해하지 못하는 JSX가 실제로 어떻게 동작할 수 있는지 설명해주세요.

힌트 · JSX가 결국 어떤 자바스크립트 함수 호출로 변환되는지, 그 변환 주체가 무엇인지의 관점에서 접근하세요.

React에서 JSX는 JavaScript XML의 약자로, JavaScript 코드 내에서 HTML과 유사한 문법으로 UI를 선언적으로 작성할 수 있게 해주는 확장 문법입니다. 브라우저는 JSX를 직접 이해하지 못…

전체 모범답안 펼치기

React에서 JSX는 JavaScript XML의 약자로, JavaScript 코드 내에서 HTML과 유사한 문법으로 UI를 선언적으로 작성할 수 있게 해주는 확장 문법입니다. 브라우저는 JSX를 직접 이해하지 못합니다. 대신, Babel과 같은 트랜스파일러가 JSX를 React.createElement() 함수 호출로 변환합니다. 이 함수 호출은 React가 이해할 수 있는 JavaScript 객체인 Virtual DOM을 생성합니다. React는 이 Virtual DOM을 실제 DOM에 효율적으로 렌더링하여 화면에 UI를 표시합니다.

#JavaScript XML#Babel#Virtual DOM#렌더링

이 질문 단독 페이지 →

Q4 기초

JSX 문법에서 class 대신 className을, for 대신 htmlFor를 쓰는 이유는 무엇인가요?

힌트 · JSX가 결국 자바스크립트라는 점과 일부 단어가 가진 언어적 의미의 관점에서 접근하세요.

JSX에서 class 대신 className을, for 대신 htmlFor를 사용하는 이유는 JSX가 결국 자바스크립트 문법을 확장한 것이기 때문입니다.

전체 모범답안 펼치기

JSX에서 class 대신 className을, for 대신 htmlFor를 사용하는 이유는 JSX가 결국 자바스크립트 문법을 확장한 것이기 때문입니다.

class는 자바스크립트의 예약어이기 때문에, JSX에서 HTML의 class 속성을 그대로 사용하면 자바스크립트 문법과 충돌이 발생합니다. 이를 방지하기 위해 React는 className이라는 다른 이름을 사용하도록 했습니다.

마찬가지로 for도 자바스크립트에서 반복문 등에 사용되는 예약어입니다. 따라서 HTML의 for 속성을 JSX에서 사용하려면 htmlFor라는 이름을 사용해야 합니다.

이러한 규칙 덕분에 JSX는 자바스크립트 코드 안에서 HTML과 유사한 구조를 안전하게 사용할 수 있게 됩니다.

#HTML 속성#JavaScript 예약어#충돌 방지#React

이 질문 단독 페이지 →

Q5 기초

함수형 컴포넌트와 클래스 컴포넌트의 차이점은 무엇이며, 최근에는 왜 함수형 컴포넌트가 권장되나요?

힌트 · 상태와 생명주기를 다루는 방식의 차이, 그리고 Hook 도입이 가져온 변화의 관점에서 접근하세요.

함수형 컴포넌트와 클래스 컴포넌트의 가장 큰 차이점은 상태와 생명주기를 다루는 방식입니다. 클래스 컴포넌트는 this.state와 this.setState로 상태를 관리하고, componentDidMount 같은 생…

전체 모범답안 펼치기

함수형 컴포넌트와 클래스 컴포넌트의 가장 큰 차이점은 상태와 생명주기를 다루는 방식입니다. 클래스 컴포넌트는 this.statethis.setState로 상태를 관리하고, componentDidMount 같은 생명주기 메서드를 사용합니다. 반면 함수형 컴포넌트는 원래 상태나 생명주기 관리가 불가능했지만, React Hooks가 도입되면서 useState로 상태를, useEffect로 생명주기 관련 로직을 다룰 수 있게 되었습니다.

최근 함수형 컴포넌트가 권장되는 이유는 Hooks 덕분에 클래스 컴포넌트의 장점을 그대로 가지면서도 더 간결하고 가독성 높은 코드를 작성할 수 있기 때문입니다. 특히 로직 재사용이 용이해지고, 복잡한 컴포넌트를 더 쉽게 관리할 수 있다는 점이 큰 장점입니다.

#Hooks#상태 관리#렌더링#생명주기 메서드#가독성

이 질문 단독 페이지 →

Q6 기초

props와 state의 차이점은 무엇인가요? 각각 누가 소유하고 변경할 수 있는지 함께 설명해주세요.

힌트 · 데이터를 누가 내려주고 누가 바꿀 수 있는지, 읽기 전용 여부의 관점에서 접근하세요.

props와 state의 가장 큰 차이점은 데이터의 소유권과 변경 가능성에 있습니다.

전체 모범답안 펼치기

props와 state의 가장 큰 차이점은 데이터의 소유권과 변경 가능성에 있습니다.

props는 부모 컴포넌트에서 자식 컴포넌트로 데이터를 전달하는 데 사용됩니다. props는 자식 컴포넌트에서 읽기 전용으로, 자식 컴포넌트 자체에서는 변경할 수 없습니다. 마치 부모가 자식에게 물려주는 용돈과 같다고 생각하시면 됩니다.

반면에 state는 컴포넌트 내부에서 관리되는 데이터입니다. state는 컴포넌트 자체에서 변경할 수 있으며, 컴포넌트의 상태 변화에 따라 UI를 업데이트하는 데 사용됩니다. 이는 컴포넌트가 자체적으로 가지는 변수와 비슷합니다.

정리하자면, props는 부모가 내려주는 읽기 전용 데이터이고, state는 컴포넌트 스스로가 관리하고 변경할 수 있는 데이터입니다.

#props#state#부모 컴포넌트#자식 컴포넌트#불변성

이 질문 단독 페이지 →

Q7 기초

React에서 props는 왜 읽기 전용(read-only)이어야 하나요? 자식 컴포넌트에서 props를 직접 수정하면 어떤 문제가 생기나요?

힌트 · 컴포넌트를 순수 함수처럼 다루는 것과 데이터 흐름의 예측 가능성 관점에서 접근하세요.

React에서 props가 읽기 전용인 이유는 크게 두 가지입니다. 첫째, 단방향 데이터 흐름을 유지하기 위해서입니다. 부모 컴포넌트에서 자식 컴포넌트로 데이터가 전달되면, 자식 컴포넌트는 이 데이터를 그대로 사용해…

전체 모범답안 펼치기

React에서 props가 읽기 전용인 이유는 크게 두 가지입니다. 첫째, 단방향 데이터 흐름을 유지하기 위해서입니다. 부모 컴포넌트에서 자식 컴포넌트로 데이터가 전달되면, 자식 컴포넌트는 이 데이터를 그대로 사용해야 합니다. 만약 자식 컴포넌트에서 props를 직접 수정해버리면, 부모 컴포넌트의 상태와 자식 컴포넌트의 상태가 불일치하게 되어 예측 불가능한 동작을 야기할 수 있습니다.

둘째, 컴포넌트를 순수 함수처럼 다루기 위함입니다. 순수 함수는 동일한 입력에 대해 항상 동일한 출력을 보장하며, 외부 상태를 변경하지 않습니다. props를 읽기 전용으로 유지함으로써 React 컴포넌트 역시 이러한 순수 함수의 특성을 갖게 되어, 코드의 예측 가능성을 높이고 디버깅을 훨씬 용이하게 만듭니다.

자식 컴포넌트에서 props를 직접 수정하면, 해당 컴포넌트뿐만 아니라 데이터를 전달한 부모 컴포넌트의 렌더링에도 예기치 않은 영향을 줄 수 있습니다. 이는 복잡한 애플리케이션에서 데이터 흐름을 추적하기 어렵게 만들고, 예상치 못한 버그를 발생시키는 주요 원인이 됩니다. 따라서 자식 컴포넌트에서 데이터를 변경해야 할 경우, props를 직접 수정하는 대신 부모 컴포넌트의 상태를 변경하는 콜백 함수를 props로 전달받아 사용하는 것이 올바른 방법입니다.

#단방향 데이터 흐름#예측 가능성#디버깅 용이성#상태 관리

이 질문 단독 페이지 →

읽기만으론 부족합니다 — 직접 말해보세요

패스잇 앱에서 React 질문에 직접 답하면 AI가 1:1로 답변을 코칭합니다.

React 면접 질문 — 중급

Q8 중급

React의 useEffect Hook의 의존성 배열(dependency array)은 어떻게 동작하나요?

힌트 · 빈 배열, 특정 값, 생략했을 때의 차이를 설명해보세요.

useEffect Hook의 의존성 배열은 effect가 언제 다시 실행될지를 결정하는 중요한 역할을 합니다.

전체 모범답안 펼치기

useEffect Hook의 의존성 배열은 effect가 언제 다시 실행될지를 결정하는 중요한 역할을 합니다.

의존성 배열이 비어있으면 ([]), 컴포넌트가 처음 마운트될 때 딱 한 번만 effect가 실행됩니다. 컴포넌트가 언마운트될 때 정리(cleanup) 함수가 있다면 그때 실행됩니다.

특정 값을 의존성 배열에 넣으면 ([count]), 해당 값들이 이전 렌더링과 비교해서 변경되었을 때만 effect가 다시 실행됩니다. 이를 통해 불필요한 effect 실행을 막고 성능을 최적화할 수 있습니다.

의존성 배열을 생략하면, 컴포넌트가 렌더링될 때마다 effect가 실행됩니다. 이는 상태나 props가 변경될 때마다 effect를 실행해야 하는 경우에 유용하지만, 무분별하게 사용하면 성능 문제를 일으킬 수 있습니다. 따라서 의존성 배열을 신중하게 관리하는 것이 중요합니다.

#의존성#렌더링#상태#props#최적화

이 질문 단독 페이지 →

Q9 중급

React에서 상태 관리 라이브러리를 사용하는 이유는 무엇인가요?

힌트 · prop drilling 문제와 전역 상태 관리의 필요성을 설명해보세요.

React에서 상태 관리 라이브러리를 사용하는 주된 이유는 컴포넌트 간의 상태 공유와 관리를 효율적으로 하기 위해서입니다.

전체 모범답안 펼치기

React에서 상태 관리 라이브러리를 사용하는 주된 이유는 컴포넌트 간의 상태 공유와 관리를 효율적으로 하기 위해서입니다.

React는 단방향 데이터 흐름을 가지지만, 앱 규모가 커질수록 props를 통해 데이터를 전달하는 과정이 복잡해지는 "prop drilling" 문제가 발생할 수 있습니다. 이 경우, 상태 관리 라이브러리를 사용하면 특정 컴포넌트에서 상태를 변경했을 때, 관련된 다른 컴포넌트들이 자동으로 업데이트되도록 할 수 있습니다.

또한, 앱 전체에서 공유해야 하는 전역 상태(예: 사용자 인증 정보, 테마 설정 등)를 관리하는 데 유용합니다. Redux, Zustand, Recoil과 같은 라이브러리는 전역 상태를 중앙 집중식으로 관리하고, 예측 가능한 방식으로 상태 변화를 추적할 수 있도록 도와줍니다. 결과적으로 코드의 유지보수성과 테스트 용이성을 높일 수 있습니다.

#상태#컴포넌트#props#전역#유지보수

이 질문 단독 페이지 →

Q10 중급

React의 useState와 useReducer의 차이점과 사용 기준은 무엇인가요?

힌트 · 상태 복잡도, 업데이트 로직, 테스트 용이성을 비교해보세요.

useState와 useReducer는 React에서 상태 관리를 위한 Hook입니다. 가장 큰 차이점은 상태 업데이트 로직의 복잡성에 있습니다.

전체 모범답안 펼치기

useState와 useReducer는 React에서 상태 관리를 위한 Hook입니다. 가장 큰 차이점은 상태 업데이트 로직의 복잡성에 있습니다.

useState는 간단한 상태를 관리할 때 유용합니다. 상태가 단순하고 업데이트 로직이 간단할 때 직관적으로 사용할 수 있습니다. 예를 들어, 단순히 숫자를 증가시키거나 문자열을 변경하는 경우에 적합합니다.

반면, useReducer는 상태가 복잡하고 업데이트 로직이 여러 액션에 따라 달라질 때 효과적입니다. 상태 변화를 예측 가능하게 만들고, 상태 업데이트 로직을 reducer 함수로 분리하여 관리하므로 유지보수성이 높아집니다. 또한, 액션과 상태 변화를 분리하여 테스트하기 용이합니다.

useReducer는 useState보다 초기 설정이 복잡하지만, 복잡한 상태 관리를 위한 강력한 도구입니다. 상태의 복잡성과 업데이트 로직을 고려하여 적절한 Hook을 선택하는 것이 중요합니다.

#상태 관리#복잡성#예측 가능성#액션#불변성

이 질문 단독 페이지 →

Q11 중급

React의 useCallback과 useMemo의 차이점과 사용 시 주의사항은?

힌트 · 메모이제이션 대상(함수 vs 값)과 과도한 최적화 문제를 생각해보세요.

useCallback과 useMemo는 React의 렌더링 최적화를 위한 Hook입니다. 둘 다 메모이제이션을 사용하지만, 메모이제이션 대상이 다릅니다.

전체 모범답안 펼치기

useCallback과 useMemo는 React의 렌더링 최적화를 위한 Hook입니다. 둘 다 메모이제이션을 사용하지만, 메모이제이션 대상이 다릅니다.

useCallback은 함수 자체를 메모이제이션합니다. 컴포넌트가 리렌더링될 때마다 새로운 함수가 생성되는 것을 방지하여, 자식 컴포넌트에게 props로 전달되는 함수의 참조 동일성을 유지할 수 있습니다. 의존성 배열에 따라 함수 재생성 여부가 결정됩니다.

useMemo는 특정 값을 메모이제이션합니다. 복잡한 연산의 결과를 저장해두고, 의존성 배열이 변경되지 않는 한 저장된 값을 재사용하여 불필요한 연산을 줄입니다.

사용 시 주의사항은 불필요한 최적화를 피해야 한다는 점입니다. useCallback이나 useMemo를 과도하게 사용하면 오히려 코드가 복잡해지고 성능 저하를 유발할 수 있습니다. 또한, 의존성 배열을 정확하게 관리하지 않으면 예상치 못한 버그가 발생할 수 있습니다. 예를 들어, 의존성 배열에 필요한 값을 빠뜨리면 메모이제이션이 제대로 작동하지 않을 수 있습니다.

#참조_동일성#메모이제이션#렌더링_최적화#불필요한_의존성#함수_재생성

이 질문 단독 페이지 →

Q12 중급

React에서 컴포넌트 리렌더링이 발생하는 조건과 최적화 방법에 대해 설명해주세요.

힌트 · React.memo, 상태 분리, 불변성 유지를 생각해보세요.

React 컴포넌트는 기본적으로 다음과 같은 조건에서 리렌더링됩니다.

전체 모범답안 펼치기

React 컴포넌트는 기본적으로 다음과 같은 조건에서 리렌더링됩니다.

  1. Props 변경: 컴포넌트에 전달되는 props가 이전과 달라질 때 리렌더링됩니다.
  2. State 변경: 컴포넌트 내부의 state가 setState를 통해 업데이트될 때 리렌더링됩니다.
  3. Context 변경: 컴포넌트가 구독하고 있는 Context의 값이 변경될 때 리렌더링됩니다.
  4. 부모 컴포넌트 리렌더링: 부모 컴포넌트가 리렌더링되면 자식 컴포넌트도 기본적으로 리렌더링됩니다.

리렌더링 최적화 방법으로는 다음과 같은 것들이 있습니다.

  • React.memo: props 변경을 얕게 비교하여 불필요한 리렌더링을 방지합니다. 함수형 컴포넌트에 적용할 수 있습니다.
  • PureComponent: 클래스형 컴포넌트에서 props와 state를 얕게 비교하여 리렌더링을 최적화합니다.
  • 상태 분리: 컴포넌트의 state를 필요한 부분만 관리하도록 분리하여 불필요한 리렌더링을 줄입니다.
  • 불변성 유지: state나 props를 업데이트할 때 항상 새로운 객체를 생성하여 불변성을 유지하면 React가 변경을 더 쉽게 감지하고 최적화할 수 있습니다. 예를 들어, 배열을 업데이트할 때 push 대신 concat이나 스프레드 연산자를 사용합니다.
#Props 변경#State 변경#Context 변경#PureComponent#React.memo

이 질문 단독 페이지 →

Q13 중급

React의 Context API와 상태 관리 라이브러리의 차이점과 선택 기준은?

힌트 · 성능, 복잡도, 미들웨어 필요 여부를 비교해보세요.

React Context API와 상태 관리 라이브러리는 모두 전역 상태를 관리하는 데 사용되지만, 몇 가지 중요한 차이점이 있습니다.

전체 모범답안 펼치기

React Context API와 상태 관리 라이브러리는 모두 전역 상태를 관리하는 데 사용되지만, 몇 가지 중요한 차이점이 있습니다.

Context API는 React 내장 기능으로, props drilling 없이 컴포넌트 트리 전체에 데이터를 제공할 수 있습니다. 간단한 전역 상태 관리에 유용하지만, 규모가 커질수록 성능 문제가 발생할 수 있습니다. Context 값이 변경될 때마다 Context를 사용하는 모든 컴포넌트가 리렌더링되기 때문입니다.

반면, Redux나 Zustand 같은 상태 관리 라이브러리는 더 복잡하지만, 성능 최적화에 유리합니다. Redux는 예측 가능한 상태 변화를 위해 단방향 데이터 흐름과 미들웨어를 제공하며, Zustand는 더 간단하게 상태를 관리하고 성능 최적화에 집중합니다.

선택 기준은 프로젝트 규모와 복잡도입니다. 간단한 앱이라면 Context API로 충분하지만, 규모가 크고 복잡한 앱에서는 상태 관리 라이브러리를 사용하는 것이 좋습니다. 또한, 미들웨어를 사용해야 하거나, 상태 변화를 추적하고 디버깅해야 하는 경우에도 상태 관리 라이브러리가 더 적합합니다.

#전역 상태#props drilling#Context Provider#규모 확장성#성능 최적화

이 질문 단독 페이지 →

Q14 중급

React의 제어 컴포넌트와 비제어 컴포넌트의 차이점은?

힌트 · 상태 관리 위치와 ref 사용을 비교해보세요.

React에서 제어 컴포넌트와 비제어 컴포넌트는 폼 요소의 상태 관리 방식에 따라 구분됩니다.

전체 모범답안 펼치기

React에서 제어 컴포넌트와 비제어 컴포넌트는 폼 요소의 상태 관리 방식에 따라 구분됩니다.

제어 컴포넌트는 React 컴포넌트의 상태(state)가 폼 요소의 값을 제어합니다. 즉, 폼 요소의 값은 React state에 저장되고, state가 변경될 때마다 폼 요소가 업데이트됩니다. onChange 이벤트 핸들러를 통해 state를 업데이트하는 방식으로 구현됩니다. 데이터 흐름을 예측하기 쉽고, 유효성 검사 등을 중앙 집중적으로 관리할 수 있다는 장점이 있습니다.

반면, 비제어 컴포넌트는 폼 요소의 값을 React state가 아닌 DOM 자체에 저장합니다. ref를 사용하여 DOM 요소에 직접 접근하여 값을 가져오거나 설정합니다. 초기값 설정이나 특정 상황에서만 값을 읽어올 때 유용하지만, React의 데이터 흐름에서 벗어나기 때문에 상태 관리가 복잡해질 수 있습니다.

#상태#제어#props#DOM#ref

이 질문 단독 페이지 →

React 면접 질문 — 심화

Q15 심화

React Server Components란 무엇이며, 기존 SSR과의 차이점은?

힌트 · 클라이언트/서버 컴포넌트 구분과 번들 사이즈 이점을 생각해보세요.

React Server Components는 서버에서 렌더링되는 컴포넌트입니다. 기존 SSR(ServerSide Rendering)과 가장 큰 차이점은 렌더링 위치와 번들 사이즈입니다.

전체 모범답안 펼치기

React Server Components는 서버에서 렌더링되는 컴포넌트입니다. 기존 SSR(Server-Side Rendering)과 가장 큰 차이점은 렌더링 위치와 번들 사이즈입니다.

SSR은 서버에서 HTML을 생성하여 클라이언트로 보내고, 클라이언트에서는 JavaScript를 통해 DOM을 조작하는 hydration 과정을 거칩니다. 이 과정에서 클라이언트는 서버에서 보낸 HTML과 함께 모든 컴포넌트의 JavaScript 번들을 다운로드해야 합니다.

반면, Server Components는 서버에서 렌더링된 결과만 클라이언트로 보내고, 클라이언트에서는 필요한 부분만 hydration합니다. 즉, 서버에서 실행되는 컴포넌트는 클라이언트 번들에 포함되지 않아 번들 사이즈를 크게 줄일 수 있습니다. 또한, Server Components는 데이터 페칭을 서버에서 직접 수행할 수 있어 클라이언트 측 로직을 단순화하고 성능을 향상시킬 수 있습니다.

간단히 말해, Server Components는 렌더링 위치를 서버로 옮겨 번들 사이즈를 줄이고, 클라이언트 컴포넌트와 함께 사용하여 효율적인 렌더링을 가능하게 하는 새로운 방식입니다.

#서버 컴포넌트#클라이언트 컴포넌트#렌더링 위치#스트리밍#부분적 hydration

이 질문 단독 페이지 →

Q16 심화

React의 Concurrent Mode와 useTransition, useDeferredValue에 대해 설명해주세요.

힌트 · 긴급/비긴급 업데이트 우선순위 구분을 생각해보세요.

React의 Concurrent Mode는 React가 사용자 인터랙션을 더 부드럽게 처리하기 위해 도입된 기능입니다. 핵심은 렌더링 작업을 인터럽트하고 우선순위를 부여할 수 있다는 점입니다.

전체 모범답안 펼치기

React의 Concurrent Mode는 React가 사용자 인터랙션을 더 부드럽게 처리하기 위해 도입된 기능입니다. 핵심은 렌더링 작업을 인터럽트하고 우선순위를 부여할 수 있다는 점입니다.

useTransition 훅은 상태 업데이트를 긴급한 업데이트와 비긴급한 업데이트로 나눌 수 있게 해줍니다. 예를 들어, 입력 필드에 글자를 입력하는 것은 긴급한 업데이트로 즉시 반영되어야 하지만, 검색 결과를 보여주는 것은 비긴급한 업데이트로 처리하여 화면이 멈추는 것을 방지할 수 있습니다.

useDeferredValue 훅은 값을 "지연"시켜서 렌더링 성능을 최적화하는 데 사용됩니다. 예를 들어, 복잡한 컴포넌트가 렌더링되는 동안 다른 중요한 업데이트가 먼저 처리되도록 할 수 있습니다.

이러한 기능들을 통해 React는 사용자 경험을 향상시키고, 더 복잡한 애플리케이션을 효율적으로 관리할 수 있게 되었습니다.

#비동기_렌더링#우선순위#Interruptible#Suspense#Transition

이 질문 단독 페이지 →

Q17 심화

React의 useImperativeHandle Hook의 용도와 사용법에 대해 설명해주세요.

힌트 · 부모에게 노출할 인스턴스 값 커스터마이징을 생각해보세요.

useImperativeHandle 훅은 React 컴포넌트가 부모 컴포넌트에게 노출하는 인스턴스 값을 커스터마이징할 때 사용됩니다. useRef 훅과 forwardRef를 함께 사용하여 자식 컴포넌트의 DOM 노드…

전체 모범답안 펼치기

useImperativeHandle 훅은 React 컴포넌트가 부모 컴포넌트에게 노출하는 인스턴스 값을 커스터마이징할 때 사용됩니다. useRef 훅과 forwardRef를 함께 사용하여 자식 컴포넌트의 DOM 노드에 직접 접근하는 대신, 부모 컴포넌트가 사용할 수 있는 명령형 API를 정의할 수 있습니다.

예를 들어, 비디오 플레이어 컴포넌트가 있다고 가정했을 때, 부모 컴포넌트에서 play(), pause() 같은 메서드를 직접 호출하고 싶을 수 있습니다. useImperativeHandle을 사용하면 이러한 메서드들을 정의하고 부모 컴포넌트에게 필요한 기능만 선택적으로 노출할 수 있습니다. 이를 통해 자식 컴포넌트의 내부 구현을 숨기고 더 깔끔한 API를 제공할 수 있습니다.

useImperativeHandle(ref, () => ({
  play: () => {
    // 비디오 재생 로직
  },
  pause: () => {
    // 비디오 일시 정지 로직
  }
}));

useImperativeHandle은 꼭 필요한 경우에만 사용해야 하며, 일반적으로는 React의 데이터 흐름 방식을 따르는 것이 좋습니다.

#useRef#부모 컴포넌트#인스턴스#명령형#DOM API

이 질문 단독 페이지 →

Q18 심화

React에서 setState 호출이 항상 비동기적으로 동작한다고 말할 수 있을까요? React 18 이전과 이후의 자동 배치(automatic batching) 동작 차이를 setTimeout이나 Promise 콜백 내부에서의 setState를 예로 들어 설명해주세요.

힌트 · React 18에서 배치가 이벤트 핸들러 밖으로 확장된 점과 그 이전의 동작 차이 관점에서 접근하세요.

React에서 setState 호출이 항상 비동기적으로 동작한다고 단정하기는 어렵습니다. React 18 이전에는 이벤트 핸들러 내에서 호출된 setState만 비동기적으로 동작하여 여러 setState 호출을 묶어…

전체 모범답안 펼치기

React에서 setState 호출이 항상 비동기적으로 동작한다고 단정하기는 어렵습니다. React 18 이전에는 이벤트 핸들러 내에서 호출된 setState만 비동기적으로 동작하여 여러 setState 호출을 묶어(batching) 한 번의 리렌더링으로 처리했습니다. 하지만 setTimeout이나 Promise 콜백과 같이 이벤트 핸들러 외부에서 호출된 setState는 각각 별도의 비동기 작업으로 처리되어 여러 번의 리렌더링을 유발했습니다.

React 18부터는 자동 배치(automatic batching)가 도입되어 이벤트 핸들러 외부의 setState 호출도 자동으로 배치됩니다. 즉, setTimeout이나 Promise 콜백 안에서 여러 번의 setState를 호출하더라도 React 18에서는 이를 묶어서 한 번의 리렌더링으로 처리합니다. 이는 성능 향상에 크게 기여합니다.

예를 들어, React 18 이전에는 setTimeout 안에서 setState를 두 번 호출하면 두 번의 리렌더링이 발생했지만, React 18에서는 한 번의 리렌더링만 발생합니다. 이처럼 React 18 이전과 이후의 자동 배치 동작 차이는 setState가 비동기적으로 처리되는 방식과 리렌더링 횟수에 직접적인 영향을 미칩니다.

#비동기#자동 배치#React 18#setTimeout#Promise

이 질문 단독 페이지 →

Q19 심화

JSX는 결국 React.createElement(또는 jsx 런타임) 호출로 변환됩니다. 이 변환 결과인 element 객체가 어떤 구조를 가지며, 이것이 실제 DOM이 아니라 '설명(description)'에 불과하다는 점이 렌더링 파이프라인에서 어떤 의미를 갖는지 설명해주세요.

힌트 · JSX가 컴파일된 후 만들어지는 객체와 render 단계/commit 단계의 분리 관점에서 접근하세요.

JSX는 결국 React.createElement 호출로 변환되어 React Element 객체를 생성합니다. 이 객체는 실제 DOM 노드가 아니라, 어떤 종류의 DOM 노드를 어떤 속성과 자식으로 렌더링해야 하는지…

전체 모범답안 펼치기

JSX는 결국 React.createElement 호출로 변환되어 React Element 객체를 생성합니다. 이 객체는 실제 DOM 노드가 아니라, 어떤 종류의 DOM 노드를 어떤 속성과 자식으로 렌더링해야 하는지에 대한 '설명'입니다.

이 '설명'은 React의 렌더링 파이프라인에서 매우 중요합니다. React는 이 Element 객체들을 기반으로 가상 DOM(Virtual DOM)을 구축합니다. 사용자가 UI를 업데이트하면, React는 이전 가상 DOM과 새로운 가상 DOM을 비교하여 변경된 부분만을 식별합니다. 이 과정을 Reconciliation이라고 합니다.

Reconciliation을 통해 최소한의 변경 사항을 파악한 후, React는 실제 DOM에 해당 변경 사항만을 적용합니다. 이러한 '설명' 기반의 접근 방식 덕분에 React는 선언적(Declarative) UI를 구현할 수 있으며, 개발자는 UI의 최종 상태만을 기술하면 React가 효율적으로 DOM을 업데이트해줍니다. 즉, Element 객체는 실제 DOM 조작을 추상화하여 성능 최적화를 가능하게 하는 핵심 요소입니다.

#Virtual DOM#React Element#Reconciliation#Declarative

이 질문 단독 페이지 →

Q20 심화

함수형 컴포넌트는 클로저를 기반으로 동작합니다. 이로 인해 발생하는 'stale closure(오래된 클로저)' 문제가 무엇이며, setInterval이나 이벤트 구독 안에서 state를 참조할 때 왜 의도치 않은 값이 보이는지, 그리고 이를 해결하는 방법을 설명해주세요.

힌트 · 각 렌더가 자신만의 props/state 스냅샷을 캡처한다는 점과 의존성 배열·ref를 통한 해결 관점에서 접근하세요.

함수형 컴포넌트는 렌더링될 때마다 새로운 함수 스코프를 생성하고, 이 스코프는 해당 렌더링 시점의 props와 state 값을 '캡처'합니다. 이것이 바로 클로저의 동작 방식입니다.

전체 모범답안 펼치기

함수형 컴포넌트는 렌더링될 때마다 새로운 함수 스코프를 생성하고, 이 스코프는 해당 렌더링 시점의 props와 state 값을 '캡처'합니다. 이것이 바로 클로저의 동작 방식입니다.

'Stale closure' 문제는 이 캡처된 오래된 스코프가 계속 유지되어 발생하는 현상입니다. 예를 들어, setInterval이나 이벤트 리스너 안에서 state 값을 참조할 때, 컴포넌트가 재렌더링되어 state가 업데이트되었더라도, setInterval이나 이벤트 리스너는 처음 생성될 때의 오래된 state 값을 계속 참조하게 됩니다. 그래서 의도치 않게 이전 값이나 예상치 못한 값이 보이는 것이죠.

이 문제를 해결하는 방법은 크게 두 가지입니다.

첫째, useEffect의 의존성 배열을 활용하는 것입니다. useEffect의 두 번째 인자인 의존성 배열에 state나 props를 명시하면, 해당 값이 변경될 때마다 useEffect 내부의 함수가 다시 실행되어 최신 값을 참조하게 됩니다. 하지만 setInterval처럼 주기적으로 실행되어야 하는 경우, 의존성 배열에 모든 state를 넣으면 너무 자주 클린업되고 다시 설정되어 성능 문제가 발생할 수 있습니다.

둘째, useRef를 사용하는 것입니다. useRef는 컴포넌트의 생명주기 동안 값이 유지되면서도, 값이 변경되어도 컴포넌트를 재렌더링하지 않습니다. 따라서 setInterval이나 이벤트 리스너 안에서 최신 state 값을 참조하고 싶을 때, 해당 state를 useRef에 저장해두고 useRef.current 값을 참조하면 stale closure 문제를 피할 수 있습니다. useEffect 안에서 useRef를 업데이트하고, setInterval 등에서는 useRef를 참조하는 방식으로 구현하면 됩니다.

#클로저#상태(state)#재렌더링#useRef#useEffect

이 질문 단독 페이지 →

Q21 심화

단방향 데이터 흐름을 따르는 React에서, 부모-자식 간 상태를 끌어올리는(lifting state up) 패턴이 깊은 컴포넌트 트리에서 'prop drilling' 문제를 일으킵니다. 이 문제를 Context, composition(children 합성), 상태 관리 라이브러리 중 무엇으로 풀지 판단하는 기준을 설명해주세요.

힌트 · 재사용성·리렌더 범위·결합도 측면에서 각 해법의 트레이드오프 관점에서 접근하세요.

prop drilling 문제는 Context API, composition, 상태 관리 라이브러리로 해결할 수 있습니다.

전체 모범답안 펼치기

prop drilling 문제는 Context API, composition, 상태 관리 라이브러리로 해결할 수 있습니다.

Context API는 전역적으로 접근해야 하는 상태에 적합합니다. 다만, 상태 변경 시 관련 없는 컴포넌트까지 리렌더링될 수 있어 성능 이슈가 발생할 수 있습니다.

Composition은 컴포넌트 재사용성을 높이고 결합도를 낮추는 데 효과적입니다. children prop을 활용하여 상태를 전달하는 방식은 prop drilling을 완화하지만, 상태가 깊이 중첩되면 여전히 복잡해질 수 있습니다.

상태 관리 라이브러리는 복잡하고 빈번하게 변경되는 전역 상태 관리에 가장 강력한 솔루션입니다. Redux, Zustand 등은 상태 변경 범위를 명확히 하고 최적화 기능을 제공하여 성능 문제를 해결하는 데 유리합니다.

결론적으로, 상태의 범위와 변경 빈도, 컴포넌트 트리 깊이, 그리고 팀의 선호도 등을 종합적으로 고려하여 가장 적합한 방법을 선택해야 합니다.

#Context API#composition#상태 관리 라이브러리#prop drilling#컴포넌트 트리 깊이

이 질문 단독 페이지 →

함께 보면 좋은 프론트엔드 개발 면접 질문

← 전체 면접 질문 카테고리 보기

보유한 React 질문은 이게 전부가 아닙니다

패스잇 앱에는 직무별 면접 질문 수천 개와 모범답안이 담겨 있습니다. AI 모의면접으로 직접 답하고, 약점을 분석받아 보세요.