[프론트엔드 면접 준비] React 질문 목록 (feat. Next.js)

Rachel·2024년 8월 3일
0
post-thumbnail

최근 면접 준비를 하면서 공부한 React 중요 개념에 대해 정리해봤습니다.
프론트엔드 면접 질문 목록을 찾아보면 대부분 중요한 질문들이 비슷한데 해당 질문 목록과 실제 면접 경험 + 본인의 프로젝트 경험을 넣어 내용 정리했습니다.
참고로 실제 면접에서 받은 질문들 앞에는 ⭐️ 별을 붙였습니다.

리액트란?

React는 사용자 인터페이스를 구축하기 위한 자바스크립트 라이브러리로 Facebook에서 개발하고 관리합니다. 빠르고 효율적인 렌더링을 통해 동적인 웹 애플리케이션을 쉽게 개발할 수 있도록 도와줍니다.

리액트를 사용하는 이유

React는 가상 돔을 활용하여 효율적인 UI 업데이트를 가능케 하며, 컴포넌트 기반 구조로 독립적이고 재사용 가능한 컴포넌트로 분리하여 개발해 각 상태관리와 로직을 관리할 수 있습니다. 또 큰 커뮤니티와 생태계를 갖추고 있어 다양한 라이브러리와 도구를 활용하여 빠르게 애플리케이션을 개발할 수 있습니다.

DOM이란?

DOM(Document Object Model)은 웹 페이지의 구조를 프로그래밍적으로 접근하고 조작할 수 있는 방법을 제공하는 표준 인터페이스입니다. HTML, XML 문서의 계층적 구조를 트리 형태로 표현한 것으로, 웹 브라우저가 웹 페이지를 렌더링할 때 이 구조를 사용합니다.

최상위 노드는 문서 전체를 나타내는 document 객체이고, <div>, <p> 등 웹 페이지의 각 요소는 DOM 트리의 하나의 노드로 표현됩니다. JavaScript로 DOM을 직접 조작 가능합니다. 또한 키보드 입력, 마우스 이동 등의 사용자 인터랙션에 대한 이벤트를 처리하는 메커니즘을 제공합니다.

⭐️ 가상돔이란?

참고

Virtual DOM은 실제 DOM의 복사본으로, 웹 성능을 최적화하기 위해 사용되는 DOM 관리 방법입니다. 애플리케이션 상태 변경시 가상 DOM 객체를 통해 변경된 부분만 찾아내어 이를 실제 DOM에 적용하는 기능을 합니다.

Virtual DOM의 동작 순서는 크게 Diffing, Reconciliation 두 가지로 구분할 수 있습니다. Diffing이란 가상돔에서 변경점을 찾아내는 과정을 의미하며, Reconciliation은 찾아낸 변경점을 실제 DOM에 적용하는 과정을 의미합니다.

가상돔 동작 과정

애플리케이션이 처음 실행될 때 애플리케이션의 초기 상태를 담은 Virtual DOM을 메모리 상에 하나 생성합니다. 이후 애플리케이션이 실행되면서 상태가 변경된 부분이 있는 경우, 새로운 버전의 Virtual DOM을 메모리상에 하나 더 생성합니다. 새로운 버전의 Virtual DOM이 생성된 후, 이전 버전의 Virtual DOM과 비교하는 과정이 Diffing에 돌입하고, 변경점을 찾아냅니다. 이 과정에서 두 Virtual DOM 트리의 각 노드를 비교하여 어떤 부분이 변경되었는지 확인합니다. 변경점을 찾아낸 이후에는, 실제 DOM에 적용하는 과정인 Reconciliation에 돌입합니다. 이 과정에서 변경된 부분만 실제 DOM에 업데이트하기 때문에, 브라우저 성능이 향상될 수 있는 것입니다. Reconciliation이 완료된 이후, 또 다른 변경점이 생기면 구 버전의 Virtual DOM이 폐기되고, 새로운 변경 사항을 반영한 최신 버전의 Virtual DOM이 다시 생성됩니다.

state, props 상태 변화가 생길때마다 이러한 과정이 수행되나요?

짧은 시간안에 여러 개의 state, props가 동시에 변경되면 이를 각각 처리하는 것이 아니라 한꺼번에 모아서 처리하는 Batch Update가 이루어집니다.

Virtual DOM을 사용하는 것이 그렇지 않은 것보다 좋은가요?

항상 그런 것은 아닙니다. 간단한 애플리케이션 경우에는 가상돔을 사용하는 것이 오히려 오버헤드를 초래할 수 있습니다. 가상돔 자체도 메모리 공간을 차지하고 Diffing하는 과정 역시 CPU를 활용하기 때문입니다. 다만, DOM 트리가 복잡하고, 상태 변경도 빈번하게 일어나는 대규모 애플리케이션의 경우 사람의 인지 능력으로는 정확히 어떤 DOM을 업데이트해야 하는지 식별하기 어렵기 때문에 가상돔을 사용하는 것입니다. 따라서 애플리케이션의 복잡도와 요구 사항에 맞게 가상돔 적용 여부를 정하는 것이 좋습니다.

React 18버전에서는 뭐가 달라졌나요?

React 18에서는 동시성 모드(Concurrent Mode)가 도입되어 긴 렌더링 작업을 중단하고 사용자 입력과 같은 더 중요한 작업을 먼저 처리할 수 있습니다. 자동 일괄 처리 기능(Automatic Batching)이 향상되어 이벤트 핸들러뿐만 아니라 비동기 코드 내에서도 일괄 처리가 가능해졌습니다. 또한 useTransition 훅을 사용하여 상태 업데이트의 우선순위를 구분할 수 있으며, useDeferredValue 훅을 사용해 긴급하지 않은 상태 업데이트에서 이전 값을 사용할 수 있습니다. Suspense 기능도 개선되어 데이터를 가져오는 동안 컴포넌트의 로딩 상태를 더 쉽게 관리할 수 있습니다.

Batch Update란

Batch Update(일괄 업데이트)는 여러 상태 업데이트를 하나의 단위로 묶어 한 번에 처리하는 방식입니다. React에서는 이러한 배치 업데이트를 통해 성능을 최적화할 수 있습니다. 상태 업데이트가 일어날 때마다 리렌더링이 발생하면 성능에 큰 영향을 미칠 수 있기 때문에, React는 여러 업데이트를 모아서 한 번에 처리함으로써 리렌더링 횟수를 줄입니다.

React에서의 Batch Update

React는 이벤트 핸들러 내에서 발생하는 여러 상태 업데이트를 자동으로 일괄 처리합니다. 예를 들어, 버튼 클릭 시 여러 상태를 변경해야 하는 경우, React는 각 상태 업데이트마다 리렌더링하지 않고, 모든 상태 업데이트가 완료된 후에 한 번만 리렌더링합니다.

React 18에서의 Batch Update 확장

React 18에서는 비동기 코드에서도 일괄 처리가 가능하도록 기능이 확장되었습니다. 기존에는 이벤트 핸들러 내에서만 일괄 처리가 가능했지만, 이제는 Promise나 setTimeout과 같은 비동기 작업에서도 일괄 처리가 지원됩니다.

JSX, TSX란?

JSX는 JavaScript XML로 자바스크립트 코드 안에 HTML과 같은 구문을 사용할 수 있게 해줘 이를 통해 UI 구조를 직관적으로 작성할 수 있습니다.
TSX란 TypeScript XML로 JSX와 유사하지만 타입스크립트의 타입 시스템을 활용할 수 있습니다. 이를 활용하면 타입 체크를 통해 더 안전한 코드를 작성할 수 있습니다.

SPA, CSR, SSR, SSG의 개념

SPA는 단일 페이지 애플리케이션으로 초기에 필요한 코드를 모두 로드한 후, 페이지를 다시 로드하지 않고 동적으로 콘텐츠를 업데이트하는 방식입니다.

CSR는 클라이언트 측에서 페이지를 동적으로 렌더링하는 방식입니다. 초기 페이지 로드 후, 클라이언트가 JS를 사용하여 데이터를 가져와 렌더링합니다.

SSR은 서버 측에서 초기 페이지 렌더링을 수행하고, 완성된 HTML을 클라이언트에게 전달하는 방식입니다. 페이지가 서버에서 렌더링되기 때문에 초기 로딩 시간이 단축되고 SEO에 유리합니다.

SSG(Static Site Generation)는 빌드 타임에 모든 페이지를 미리 렌더링하여 정적 파일(HTML, CSS, JS)로 생성합니다. 생성된 정적 파일들은 서버나 CDN을 통해 제공됩니다.

SSR과 SSG의 차이

특성SSRSSG
렌더링 시점요청 시 서버에서 렌더링빌드 시 미리 렌더링
초기 로드 속도빠름매우 빠름
데이터 최신성최신 데이터 제공빌드 시점 이후 데이터 반영 어려움
서버 부하요청마다 서버 부하 있음거의 없음
SEO매우 좋음매우 좋음
사용 사례동적 컨텐츠, 사용자별 데이터가 많은 페이지정적 컨텐츠, 자주 변경되지 않는 페이지

SSR은 요청시마다 서버에서 HTML을 렌더링하므로 동적 컨텐츠에 적합합니다. 예를 들어, 사용자별로 다른 데이터를 보여줘야 하는 경우 대시보드나 사용자 프로필 페이지에 적합합니다. 또 SEO가 중요한 페이지 블로그나 뉴스 사이트 등에 적합합니다.

SSG는 빌드 타임에 모든 데이터를 미리 렌더링하여 정적 파일로 생성하므로 정적 컨텐츠가 많은 페이지 혹은 빠른 초기 로드가 중요한 페이지에 적합합니다.

Next.js와의 비교, Next.js의 특징

Next.js는 React를 기반으로 한 프레임워크로, 서버 사이드 렌더링(SSR)과 정적 사이트 생성(SSG)을 포함한 다양한 기능을 제공합니다.

파일/폴더 기반 라우팅, 이미지 최적화, 자동 코드 분할 등의 기능을 제공합니다.

(Next는 SEO, 페이징이 중요할 때 주로 사용하고, React는 사용자 인터랙션이 중요할 때 주로 사용합니다.)

코드 분할이란?

코드 분할(Code Splitting)은 애플리케이션의 코드베이스를 여러 개의 작은 번들로 나누는 기법을 말합니다. 이 기법을 통해 초기 로드 시간을 줄이고, 사용자가 필요로 하는 코드만을 로드함으로써 네트워크 트래픽을 줄일 수 있습니다. 또한 코드를 더 작은 모듈로 나누어 유지보수가 쉽고 특정 기능이나 페이지의 변경이 전체 애플리케이션의 미치는 영향을 줄입니다. 또한 여러 개의 작은 파일을 병렬로 로드할 수 있어 더 빠르게 애플리케이션을 사용할 수 있습니다. 이러한 성능 이점으로 코드 분할은 특히 대규모 애플리케이션에서 중요한 성능 최적화 기술 중 하나입니다.

Next.js의 Image 컴포넌트를 사용하였을 때 기존 img 태그와 다른 점을 설명해주세요.

Next.js의 Image 컴포넌트를 사용하면 이미지 최적화를 자동으로 처리해 페이지 성능을 향상시킵니다. 또한 이미지 크기를 미리 알고 있기 때문에 레이아웃 시프트를 방지할 수 있고 이미지 로딩 전 홀더 이미지 설정으로 사용자 경험을 향상시킬 수 있습니다.

레이아웃 시프트(Layout Shift)란?

이미지가 로드되기 전과 후에 페이지의 레이아웃이 변경되는 현상을 의미합니다. 이는 사용자 경험에 악영향을 미칠 수 있으며, 특히 이미지가 많은 페이지에서 문제가 됩니다.

Hydration이란?

Next.js에서 서버사이드 렌더링을 하기 전 초기 상태를 적용하는 과정을 말합니다. 서버에서 렌더링된 HTML을 클라이언트로 전달하고, 클라이언트에서 JavaScript가 실행되면서 초기 상태를 클라이언트와 동기화하는 과정을 말합니다.

⭐️ Flux 패턴이란?

Flux 패턴은 Facebook에서 만든 아키텍처 패턴으로, React에서 데이터의 흐름을 관리하는 데 사용됩니다. Flux는 단방향 데이터 흐름을 특징으로 하며, Action -> Dispatcher -> Store -> View의 흐름을 따릅니다. View에서 사용자가 상호작용하면 Action이 Dispatcher를 통해 전파되고, Store는 Action을 처리하여 View를 갱신합니다. 이 패턴은 React의 선언형 프로그래밍 스타일과 잘 맞아 데이터 변경을 명확하게 처리할 수 있습니다.

단방향 패턴의 장단점?

단방향 데이터 흐름 패턴의 장점은 데이터가 항상 한 방향으로 흐르기 때문에 상태 변화의 흐름을 예측 가능하고 쉽게 추적할 수 있어 디버깅과 문제 해결에 용이합니다. 또 상태 관리가 명확하게 이루어져 코드의 가독성과 유지보수성이 향상됩니다. 각 컴포넌트는 자신의 상태와 props만 신경쓰면 됩니다. 또한 상태가 중앙에서 관리되므로 상태 변경이 일관되게 관리되어 데이터의 일관성이 유지될 수 있습니다. 추가로 상태와 뷰가 명확하게 분리되어 있어 개별 컴포넌트의 테스트가 쉬워집니다.

단점은 설정과 보일러플레이트 코드가 많을 수 있으며, 초기 학습 곡선이 존재합니다.

⭐️ 다른 디자인 패턴과의 비교

  1. MVC (Model-View-Controller)
    MVC 패턴은 애플리케이션을 모델, 뷰, 컨트롤러의 세 가지 주요 컴포넌트로 분리합니다. 모델은 데이터와 비즈니스 로직을 관리하고, 뷰는 사용자 인터페이스를 관리하며, 컨트롤러는 모델과 뷰 사이의 상호작용을 관리합니다.

    • 장점: 코드의 관심사를 분리하여 유지보수성과 재사용성을 높입니다.
    • 단점: 컴포넌트 간의 상호작용이 복잡해질 수 있으며, 특히 대규모 애플리케이션에서 컨트롤러가 비대해질 수 있습니다.
  2. MVVM (Model-View-ViewModel)
    MVVM 패턴은 모델, 뷰, 뷰모델로 구성됩니다. 뷰모델은 뷰와 모델 사이의 데이터 바인딩을 관리하여 뷰가 모델의 상태 변화를 쉽게 반영할 수 있게 합니다.

    • 장점: 데이터 바인딩을 통해 뷰와 모델 간의 상호작용을 단순화하고, 뷰와 모델의 분리를 강화합니다.
    • 단점: 데이터 바인딩이 과도하게 사용되면 디버깅이 어려워질 수 있습니다.
  3. Redux
    Redux는 Flux 패턴에서 발전한 상태 관리 라이브러리로, 단일 스토어와 순수 함수인 리듀서(Reducer)를 사용합니다.

    • 장점: 상태 변화가 예측 가능하며, 중간 상태를 쉽게 추적하고 디버깅할 수 있습니다.
    • 단점: 설정과 보일러플레이트 코드가 많을 수 있으며, 초기 학습 곡선이 존재합니다.

단방향 바인딩, 양방향 바인딩 차별점 말해주세요.

단방향 바인딩은 데이터가 한 방향으로 흐르고, 양방향 바인딩은 데이터가 양방향으로 흐르는 차이가 있습니다. 단방향 바인딩은 주로 모델에서 뷰로 데이터가 전달되고 뷰의 변경은 모델의 영향을 주지 않지만 양방향 바인딩은 모델, 뷰 모두 서로가 영향을 줍니다. 따라서 단방향 바인딩이 데이터 흐름이 단방향이기때문에 디버깅이 용이하고 코드의 복잡성이 낮습니다. 양방향 바인딩은 이러한 것이 상대적으로 어렵지만, 사용자 인터페이스 반응성이 더 높습니다. 양방향 데이터 바인딩을 제공하는 것은 Angular, Vue.js가 있습니다.

선언적 프로그래밍과 명령형 프로그래밍의 차이를 아시나요?

선언적 프로그래밍 (Declarative Programming)은 “무엇을” 수행할 것인지를 기술하는 프로그래밍 패러다임입니다. 즉, 원하는 결과가 무엇인지를 설명하고, 그것을 어떻게 수행할지는 명시하지 않습니다. 예를 들어 함수형 프로그래밍, SQL, 리액트 등이 있습니다.

명령형 프로그래밍(Imperative Programming)은 “어떻게” 수행할 것인지를 기술하는 프로그래밍 패러다임입니다. 즉, 프로그램이 수행할 일련의 절차나 단계를 명령어로 명확하게 기술합니다.

함수형 프로그래밍이란?

함수형 프로그래밍은 함수를 일급 시민으로 취급하고, 부작용을 피하며, 순수 함수를 선호하는 선언적 프로그래밍 방식입니다.

⭐️ React의 생명 주기에 대해 설명하세요.

리액트의 생명주기는 마운트(mount), 업데이트(updated), 언마운트(unmount) 크게 세단계로 분류됩니다.
마운트는 컴포넌트가 처음 DOM에 삽입되는 단계를 말하고, 업데이트는 컴포넌트가 다시 렌더링될 때 발생하는 단계입니다. 주로 props나 상태 변화에 의해 트리거됩니다. 마지막으로 컴포넌트가 DOM에서 제거되는 단계를 언마운트라고 합니다.

⭐️ 리액트에서 이러한 생명주기를 사용하는 이유는?

리액트에서 생명주기 메서드를 사용하는 이유는 컴포넌트의 생성, 업데이트, 제거 시점을 효과적으로 관리하기 위해서입니다.
업데이트를 통해 UI를 최신 상태로 유지하고 컴포넌트가 제거될 때 타이머나 구독을 정리하여 메모리 누수를 방지합니다. 또한 불필요한 리렌더링을 방지하여 성능을 개선합니다. 즉, 생명주기 메서드는 컴포넌트의 상태를 관리하고, 성능을 최적화하며, 자원을 적절히 정리하는 데 도움을 줍니다.

⭐️ 리액트에서 말고 소프트웨어 전반에서 사용되는 생명주기 개념에 대해 아시나요?

생명주기는 소프트웨어가 시작되고, 성장하며, 유지되고, 결국에는 종료되는 과정을 말합니다. 즉 소프트웨어가 처음 개발되기부터, 배포, 유지보수까지의 전체 과정을 말합니다.

주로 '요구사항 분석 -> 설계 -> 개발 -> 테스트 -> 배포 -> 유지보수' 과정을 따릅니다.

이러한 생명주기 단계는 소프트웨어가 안정적이고 효과적으로 운영될 수 있도록 보장해줍니다. 계속해서 개선하고 문제를 해결하면서 소프트웨어의 품질과 사용자 만족도를 유지하는 데 필수적입니다.

⭐️ 리액트 훅이란?

리액트 훅이란 함수형 컴포넌트에서 상태와 생명주기 메서드를 사용할 수 있도록 해주는 기능입니다. React 16.8에서 도입된 훅은 클래스형 컴포넌트의 복잡한 구조를 피하고, 함수형 컴포넌트를 이용해 더 간결하고 직관적인 코드를 작성할 수 있게 합니다.

React 주요 훅

  1. useState:

    • 상태 변수를 선언하고, 해당 변수를 갱신할 수 있는 함수도 반환합니다.
    const [count, setCount] = useState(0);
    • count는 상태 변수, setCount는 상태를 갱신하는 함수입니다.
  2. useEffect:

    • 컴포넌트가 렌더링된 이후에 실행될 부수 효과(side effects)를 수행합니다. 예를 들어, 데이터 페칭, 구독(subscription) 설정 등이 있습니다.
    useEffect(() => {
      document.title = `You clicked ${count} times`;
    }, [count]);
    • 첫 번째 인자는 수행할 함수, 두 번째 인자는 의존성 배열입니다. 배열에 포함된 값이 변경될 때마다 이 함수가 실행됩니다.
  3. useContext:

    • 컴포넌트 트리 전체에서 데이터를 공유할 수 있게 해주는 Context API를 사용합니다.
    const value = useContext(MyContext);
  4. useReducer:

    • 상태 관리 로직을 더 세밀하게 제어할 수 있게 해줍니다. useState의 대안으로, 복잡한 상태 로직을 다룰 때 유용합니다.
    const [state, dispatch] = useReducer(reducer, initialState);
  5. useCallback:

    • 메모이제이션된 콜백 함수를 반환하여, 컴포넌트가 리렌더링될 때마다 동일한 함수를 생성하지 않도록 합니다.
    const memoizedCallback = useCallback(() => {
      doSomething(a, b);
    }, [a, b]);
  6. useMemo:

    • 메모이제이션된 값을 반환하여, 컴포넌트가 리렌더링될 때마다 동일한 값을 생성하지 않도록 합니다.
    const memoizedValue = useMemo(() => computeExpensiveValue(a, b), [a, b]);
  7. useRef:

    • 변경 가능한 ref 객체를 생성하여, DOM 요소나 클래스 인스턴스 같은 것을 참조할 수 있습니다.

⭐️ 프로젝트에서 상태관리 어떻게 하셨나요?

프로젝트시 사용자 로그인 정보 등 전역 상태 관리가 필요한 데이터가 생겨 다양한 전역 상태 관리 라이브러리를 고민했습니다. 그 중 팀원간 협의를 거쳐 Zustand를 사용했습니다. 그 이유는 팀원간 공통적으로 사용할 수 있는 상태 관리 라이브러리가 없어 새로운 라이브러리를 선택해야 했고 ContextAPI, RTX 등 다양한 라이브러리를 고민하다 짧은 프로젝트 기간 내 가장 간단하고 직관적인 문법으로 쉽게 사용할 수 있고, 보일러플레이트 코드도 없어 간편한 Zustand를 사용했습니다.

React에서 리렌더링되는 3가지 조건

  1. 부모 컴포넌트 리렌더링될 때
  2. props가 변경될 때
  3. state가 변경될 때

⭐️ Props와 State의 차이점

Props는 부모 컴포넌트에서 자식 컴포넌트로 전달되는 데이터입니다. 이는 읽기 전용입니다.

State는 컴포넌트 내부에서 관리되는 동적인 데이터를 의미합니다. 컴포넌트 내부에서 변경 가능합니다.

Props Drilling이란?

Props Drilling은 React 애플리케이션에서 부모 컴포넌트로부터 자식 컴포넌트로 데이터나 함수를 전달할 때 발생하는 문제를 의미합니다. 이는 데이터나 콜백 함수가 여러 계층의 컴포넌트를 통해 깊게 전달될 때 발생합니다.

Props Drilling은 컴포넌트 간의 의존성을 증가시키고 재사용성을 감소시킵니다. 또한 구조가 복잡해져 유지보수가 어려워질 수 있습니다.

컴포넌트 구조를 재설계해 props drilling을 줄이거나 Context API, Redux 등의 상태 관리 라이브러리를 사용해 해결할 수 있습니다.

⭐️ 리액트에서 성능 최적화를 위해 사용할 수 있는 최적화 도구에 대해 아는대로 설명해주세요.

리액트 확장 프로그램(React Dev Tools)을 이용하여 색상으로 렌더링 빈도를 확인하고 불필요한 리렌더링이 발생하지 않도록 최적화할 수 있습니다. 또한 Lighthouse를 통해 성능, 웹 접근성, SEO, 초기 렌더링 시간, 권장 사항 등을 확인하고 이를 최적화할 수 있습니다.


💬 실제 면접 경험을 공유하자면 암기식 기술 질문을 계속 하는 곳도 있고 그런 질문 하나 없이 프로젝트 기반 질문만 하는 곳도 있었습니다.
제가 느끼기에는 자신이 한 프로젝트, 사용한 기술 기반으로 꼬리 질문을 준비하는 것이 제일 중요하고 나머지는 회사마다 차이가 크다고 느꼈습니다.
실제로 '리액트가 뭔가요?' 같은 질문은 받은 적이 없고 동작 원리를 이해하는 부분은 중요하다고 생각합니다. 기본 질문 외에 답변도 프로젝트 경험에 따라 달라질 수 있으니 참고해주세요.

추가하면 좋은 부분이나 잘못된 점이 있다면 댓글 남겨주세요. 감사합니다 :)


참고 자료

📌 면접 준비 참고하기 좋은 영상

bluevulpe블루불페 - 프론트엔드 주니어 기술 면접 답변 회고(feat.2023상반기이직준비)

프론트맨 - 프론트엔드 기술 면접 단골 질문

라메개발자 - 프론트엔드 개발자 취업을 위한 면접 경험 공유 | 스타트업 | 대기업

인디스워크 - 프론트엔드 리드가 알려주는 개발자 채용과 면접 진행 방법

profile
기존 블로그: https://hi-rachel.tistory.com

0개의 댓글