React 인터뷰 대비 질문과 답변 15

Do Junggeun·2020년 7월 31일
53
post-thumbnail

15 React Interview Questions with Solutions

전 세계에서 개발자에 대한 수요가 공급을 앞지르고 있으며 리액트의 인기는 사그라들 기미가 보이지 않습니다. 경험이 적은 개발자(혹은 일정 기간 취업 시장을 떠나 있던 개발자)에게는 면접을 통해 자신의 지식을 인증하는 것이 부담스러울 수 있습니다.

이 글에서 우리는 리액트의 핵심을 이해하고 효율적으로 활용하기 위해 필요한 15가지 질문을 다룹니다. 각 질문에 대해 답변을 요약하고, 추가적인 자료를 찾아볼 수 있는 링크를 제공할 것입니다.

1. Virtual DOM은 무엇인가요?

답변

Virtual DOM은 애플리케이션의 UI를 구성하는 HTML 엘리먼트를 메모리 내에서 구현한 것입니다. 컴포넌트가 다시 렌더링될 때, virtual DOM은 업데이트할 요소의 목록을 만들기 위해 기존의 DOM 모델에서 변경되는 사항을 비교합니다. DOM 전체를 다시 렌더링할 필요 없이 실제 DOM에 필요한 최소한만 변경하여 효율성이 높다는 것이 큰 장점입니다.

참고 자료

2. JSX는 무엇인가요?

답변

JSX는 HTML처럼 보이는 코드를 작성할 수 있게 해주는 자바스크립트 문법의 확장입니다. JSX는 자바스크립트 함수 호출 방식으로 컴파일되어 컴포넌트에 대한 마크업을 만들 수 있는 더 좋은 방법을 제공합니다.

이 JSX를 보세요:

<div className="sidebar" />

이것은 아래의 자바스크립트로 변환됩니다:

React.createElement(
  'div',
  {className: 'sidebar'}
)

참고 자료

3. 클래스 컴포넌트와 함수형 컴포넌트의 차이는 무엇인가요?

답변

React 16.8(hooks 도입) 이전에는 내부 state를 유지하는 데 필요한 컴포넌트를 생성하거나 생명주기 메소드(lifecycle methods)(즉, componentDidMountshouldComponentUpdate)를 활용하기 위해 클래스 기반 컴포넌트를 사용했습니다. 클래스 기반 컴포넌트는 리액트의 Component 클래스를 확장하는 ES6 클래스입니다. 또한 최소한 render() 메서드를 포함해야 합니다.

클래스 컴포넌트:

class Welcome extends React.Component {
  render() {
    return <h1>Hello, {this.props.name}</h1>;
  }
}

(hooks 도입 이전의) 함수형 컴포넌트는 state를 갖지 않으며 렌더링할 출력 결과를 리턴(반환)합니다. 함수형 컴포넌트는 클래스 기반 컴포넌트보다 심플하기 때문에 props에만 의존하는 UI을 렌더링하는데 선호됩니다.

함수형 컴포넌트:

function Welcome(props) {
  return <h1>Hello, {props.name}</h1>;
}

Note: 리액트 16.8에서 도입된 hooks 덕분에 더 이상 이 차이는 의미가 없습니다. (질문 14와 15를 보세요)

참고 자료

4. key는 어떻게 사용되나요?

답변

리액트에서 collection을 렌더링할 때 엘리먼트와 데이터 사이의 관계를 추적하기 쉽도록 반복되는 각 엘리먼트에 key를 추가하는 것이 중요합니다. 키는 고유한 ID(이상적으로는 UUID 또는 기타 고유 문자열)를 사용해야 하지만, 마지막 수단으로 Array index가 될 수 있습니다.

<ul>
  {todos.map((todo) =>
    <li key={todo.id}>
      {todo.text}
    </li>
  )};
</ul>

key를 사용하지 않으면 collection에 item을 추가하거나 제거할 때 예상치 못한 동작 결과가 발생할 수 있습니다.

참고 자료

5. state와 props의 차이는 무엇인가요?

답변

props는 부모 컴포넌트에서 자식 컴포넌트로 전달되는 데이터입니다. props는 수정될 수 없으며 표시되거나 다른 값을 계산하는데만 사용됩니다. state는 컴포넌트의 생명 주기 동안 수정될 수 있는 내부 데이터로, 다시 렌더링해도 유지됩니다.

참고 자료

6. 왜 state를 직접 변경하지 않고 setState를 이용하나요?

답변

만약 컴포넌트의 state를 직접 변경하려고 시도한다면, 리액트는 컴포넌트를 다시 렌더링해야 하는지 알 수 있는 방법이 없습니다. setState() 메소드를 사용하면 리액트는 컴포넌트의 UI를 업데이트할 수 있습니다.

보너스

보너스로, 어떻게 state의 변경이 반드시 동기적으로 이루어진다고 보장되지 않는지 이야기해볼 수 있습니다. 컴포넌트의 state를 다른 state(또는 props)를 기반으로 변경해야 하는 경우, stateprops를 두 인자(arguments)로 사용하는 setState()에 함수를 전달하면 됩니다:

this.setState((state, props) => ({
  counter: state.counter + props.increment
}));

참고 자료

7. prop으로 전달되는 값의 type을 어떻게 강제하나요? 또 prop이 필수적으로 전달되게끔 어떻게 강제하나요?

답변

컴포넌트 props의 type을 확인하기 위해서는 prop-types 패키지(리액트 15.5까지는 리액트에 포함되어 있었습니다)를 이용하여 기대되는 값의 type과 prop이 필수적(require)인지 여부를 선언할 수 있습니다.

import PropTypes from 'prop-types';
class Greeting extends React.Component {
  render() {
    return (
      <h1>Hello, {this.props.name}</h1>
    );
  }
}
Greeting.propTypes = {
  name: PropTypes.string
};

참고 자료

8. prop drilling은 무엇이고 어떻게 피할 수 있나요?

답변

prop drilling은 부모 컴포넌트에서 하위 컴포넌트(자식 컴포넌트의 자식 컴포넌트 등으)로 데이터를 전달할 때 발생하는 것으로, props를 전달하는 것 외에는 props를 필요로 하지 않는 다른 컴포넌트를 통해 “drilling”(내리꽂기) 됩니다.

컴포넌트를 리팩토링하고, 컴포넌트를 더 작은 컴포넌트들로 쪼개지 않고, state를 가장 가까운 부모 컨포넌트와만 공유함으로써 prop drilling 회피할 수 있습니다. 위계상 멀리/깊게(deep/far)떨어진 컴포넌트와 state를 공유할 때, React의 Context API 혹은 Redux와 같은 state 관리 라이브러리를 사용할 수 있습니다.

참고 자료

9. React context는 무엇인가요?

답변

리액트는 하나의 앱 안에서 복수의 컴포넌트들이 state를 공유할 때 발생하는 문제들을 해결하기 위해 context API를 제공합니다. context가 도입되기 전에는 Redex와 같은 별도의 상태 관리 라이브러리를 가져오는 것이 유일한 방법이었습니다. 그러나 많은 개발자들은 (특히 작은 앱에서) Redux가 불필요한 복잡성을 유발한다고 느꼈습니다.

참고 자료

10. Redux는 무엇인가요?

답변

Redux는 React를 위한 써드파티 state 관리 라이브러리로, context API가 개발되기 전부터 존재했습니다. Redux는 store라고 불리는 state 컨테이너의 개념을 기반으로 하는데, store 컴포넌트는 데이터를 props로 받을 수 있습니다. store를 업데이트하는 유일한 방법은 reducer를 통해 전달되는 store에 action을 보내는 것입니다. reducer는 action과 현재의 state를 받고, 새로운 state를 반환(return)하고, 구독된(subscribed) 컴포넌트를 다시 렌더링하게 만듭니다.

참고 자료

11. React 애플리케이션을 스타일링(styling)하는 보편적인 방식은 무엇인가요?

답변

리액트 컴포넌트를 스타일링하는 다양한 방법이 있고, 각각은 장단점이 있습니다. 주로 사용되는 것들은 다음과 같습니다:

  • 인라인 스타일링(Inline styling) : 프로토타입을 만들 때 훌륭하지만 한계가 많습니다 (예로, pseudo-classes를 사용할 수 없습니다)
  • 클래스 기반 CSS 스타일 : 인라인 스타일링보다 유용하고 React에 익수하지 않은 개발자들도 쉽게 사용할 수 있습니다.
  • CSS in JS 스타일링 : 컴포넌트 안에서 스타일을 자바스크립트로 선언하여 스타일링할 수 있게 해주는 많은 라이브러리가 있습니다.

참고 자료

12 제어 컴포넌트와 비제어 컴포넌트의 차이는 무엇인가요?

답변

HTML 문서에서 많은 form 엘리먼트들(<select>, <textarea>, <input> 등)은 고유한 state를 유지합니다. 비제어 컴포넌트는 DOM을 이러한 input들의 state에 대한 진짜 근원(source of truth for the state of these inputs)으로 취급합니다. 제어 컴포넌트에서 내부 state는 엘리먼트의 값(value)를 추적하기 위해 사용됩니다. input의 값이 변경되면 리액트는 input을 다시 렌더링합니다. 비제어 컴포넌트는 non-React 코드와 합칠 때(예를 들어 jQuery 플러그인의 일부를 지원해야 할 때) 유용하게 사용될 수 있습니다.

참고 자료

13. 생명주기(lifecycle) 메소드는 무엇인가요?

답변

클래스 기반 컴포넌트는 그들이 mount(DOM에 렌더링)되었을 때, unmount될 때 등과 같이 그들의 생명주기 중 특정한 시점에 호출되는 특별한 메소드를 선언할 수 있습니다. 이는 예를 들면 컴포넌트가 필요로 하는 것을 셋팅 및 해제하거나, 타이머를 설정하거나 브라우저 이벤트에 바인딩하는 데 유용합니다.

아래의 생명주기 메소드들은 컴포넌트를 불러오기 위해 사용할 수 있습니다.

  • componentWillMount: 컴포넌트가 생성된 후 DOM에 렌더링되기 전에 호출됩니다.
  • componentDidMount: 처음으로 렌더링이 끝나고 컴포넌트의 DOM 엘리먼트가 사용 가능할 때 호출됩니다.
  • componentWillReceiveProps: props가 업데이트 될 때 호출됩니다.
  • shouldComponentUpdate: 새로운 props를 받았을 때 호출되며, 성능 최적화를 위해 리랜더링을 막을 수 있습니다.
  • componentWillUpdate: 새로운 props를 받았고 shouldComponentUpdatetrue를 리턴할 때 호출됩니다.
  • componentDidUpdate: 컴포넌트가 업데이트된 후에 호출됩니다.
  • componentWillUnmount: 컴포넌트가 DOM에서 제거되기 전에 호출되어 이벤트리스너 등을 정리할 수 있게 해줍니다.

참고 자료

14. React hooks는 무엇인가요?

답변

Hooks는 클래스 기반 컴포넌트의 장점(예를 들면 내부 state와 생명주기 메소드)을 함수형 컴포넌트로 가져오려는 리액트의 시도입니다.

참고 자료

15. React hooks의 장점은 무엇인가요?

답변

React에 hooks를 도입해서 얻을 수 있는 여러 이점들은 다음과 같습니다:

  • 클래스 기반 컴포넌트, lifecycle hooks, this의 필요성이 사라집니다
  • 공통 기능을 커스텀 hook로 만들어서 로직을 재사용하기 쉬워집니다.
  • 컴포넌트 자체에서 로직을 분리할 수 있어서 읽기 쉽고 테스트하기 쉬운 코드를 작성할 수 있습니다.

참고 자료

마무리

비록 완벽하지는 않지만(React는 지속적으로 진화하고 있습니다), 이 질문들은 많은 내용을 다루고 있습니다. 이 주제들을 이해하면 React 라이브러리에 대한 훌륭한 실무 지식을 얻을 수 있을 것입니다. 제시된 참고 자료를 공부하면 더욱 깊게 이해하는데 도움이 될 것입니다.

우리는 React 인터뷰를 위한 코드 연습 가이드도 준비하고 있으니, 가까운 시일 내에 볼 수 있기를 바랍니다.

행운을 빕니다!

1개의 댓글

comment-user-thumbnail
2021년 9월 18일

좋은 포스트 너무 감사합니다!!취뽀하고 올게요!!

답글 달기