질문 출처: https://intellipaat.com/blog/interview-question/react-interview-questions/

 

1. DOM과 가상 DOM(Virtual DOM)의 차이

(답변 참고: https://velopert.com/3236)

  • 가상 DOM을 이용하면 실제 DOM에 변화를 바로 적용하는 것보다 전체적인 프로세스를 효율적으로 수행할 수 있다.
    • "효율적이다" = 전체적인 프로세스에 드는 비용이 비교적 적다.
  • 속도 차원의 문제라기 보다는, 연산 횟수 차원의 문제라고 할 수 있다. 우선 각각의 DOM 조작은 레이아웃 변화, 트리 변화 및 렌더링을 일으킨다.
    • 가상 DOM을 이용하지 않으면 변화가 있을 때마다 DOM 조작이 일어나고 이에 대한 연산이 수행되며 렌더링되기 때문에 변화를 적용할 때 드는 비용이 비교적 크다.
    • 가상 DOM을 이용하면 일종의 '오프라인' DOM 트리(이는 렌더링 되지 않는다 → 연산 비용이 적다!)에 변화들을 적용한 뒤 그 변화를 하나로 묶어서 한번에 실제 DOM에 전달하기 때문에 연산 횟수가 줄어들고 변화에 대한 비용이 비교적 작다.

 

2. 리액트란?

  • 리액트는 2011년 페이스북의 개발자들에 의해 탄생한 자바스크립트 라이브러리로서, 웹/모바일 애플리케이션의 뷰를 개발할 때 사용된다. 리액트는 컴포넌트에 기반한 접근 방식을 사용하므로, 재사용 가능성이 높은 컴포넌트를 개발할 수 있다.

 

3. 가상 DOM이란?

  • 가상 DOM은 그에 대응하는 실제 DOM을 그대로 복사한 자바스크립트 객체로서, 요소 및 요소의 어트리뷰트와 프로퍼티로 구성된 노드 트리라고 할 수 있다. 리액트의 render 함수를 사용하여 노드 트리가 생성되면, 데이터 모델의 변경 사항을 기반으로 이 노드 트리 즉 가상 DOM이 업데이트 된다.

 

4. 리액트의 주요 특징

 

5. JSX란?

  • JSX는 JavaScript XML(eXtensible Markup Language)의 약어로, HTML 요소에 유효한 자바스크립트 객체를 내장할 수 있는 자바스크립트 확장이다. 리액트에선 보통 HTML과 자바스크립트를 별도로 작성하기 보다는, JSX를 이용하여 HTML과 자바스크립트를 모두 포함하고 있는 '컴포넌트'를 생성한다.
  • JSX는 HTML보다는 자바스크립트에 가깝다고 한다. (참고: "JSX 속성 정의")

 

6. 브라우저가 JSX 파일을 읽을 수 있는가?

(답변 참고: Introducing the New JSX Transform)

  • 브라우저는 JSX 파일을 직접 읽을 수는 없다. 브라우저가 JSX 파일을 읽으려면 JSX를 자바스크립트 객체로 변환을 해야 한다. 그리고 그 변환 작업은 바벨과 같은 컴파일러를 통해 이루어진다.
  • 여기서 기존에 JSX를 사용한 파일 내에서 React를 import 했던 이유를 알 수 있다. 컴파일러를 통해 JSX 코드가 자바스크립트 코드로 변환이 되면, 아래와 같이 React.createElement()로 변환이 된다.
import React from 'react';

function App() {
  return <h1>Hello World</h1>;
}


↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓
import React from 'react';

function App() {
  return React.createElement('h1', null, 'Hello world');
}
  • 즉, React.createElement()가 정상적으로 호출되기 위해 React가 스코프에 존재해야 하는 것이다.
  • 기쁜 소식은! 2020년 10월 20일에 릴리즈 된 React 17부터는 JSX 변환에 대비하여 React를 import 하지 않아도 되게 되었다. 왜냐하면 React 17에선 바벨과 같은 컴파일러를 사용하여 JSX를 변환할 때 React.createElement로 변환하는 것이 아닌 다른 방식으로 변환하는 방식을 도입했기 때문이다. 이 새로운 방식에선 아래 코드와 같이, 컴파일러가 JSX 변환에 필요한 특수한 함수를 자동적으로 import 해오기 때문이다. (다만 훅이나 React가 제공하는 다른 기능들을 사용할 땐 여전히 React를 import 해야 한다.)
import React from 'react';

function App() {
  return <h1>Hello World</h1>;
}


↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓
// Inserted by a compiler (don't import it yourself!)
import {jsx as _jsx} from 'react/jsx-runtime';

function App() {
  return _jsx('h1', { children: 'Hello world' });
}

 

7. 리액트가 널리 사용되는 이유는?

(답변 참고: React를 사용하는 이유)

  • 리액트는 애플리케이션을 구축할 때 다음과 같은 다양한 이점을 제공하기 때문에 널리 사용된다.
    • 동적 페이지(유저 인터랙션에 따라 페이지 구성을 달리 해주어야 하는 페이지)의 유저 인터페이스를 효율적으로 유지보수 및 관리할 수 있다.
    • 구체적으로는 컴포넌트 기반 아키텍처이므로, 재사용 가능한 컴포넌트를 개발하고 여러 부분에서 가져다가 사용할 수 있어 개발 생산성이 높고 유지보수가 용이하다.
    • HTML 문법과 유사한 JSX를 사용하기 때문에, HTML을 작성하듯 코드를 작성할 수 있어 편리하며 가독성이 좋다.
    • 동적 페이지에선 유저 인터랙션에 의한 view의 변화가 빈번하다. 리액트에선 가상 DOM을 사용해서, 최종적인 변화만을 실제 DOM에 전달하기 때문에 연산 비용이 비교적 적게 든다.

 

8. 리액트를 사용할 때의 단점은 없는가?

(답변 참고: https://ral-g.tistory.com/15)

  • 앵귤러와 같은 프레임워크와 비교하자면 리액트는 단순 라이브러리이기 때문에, 더 많은 기능을 사용하고자 한다면 Redux, Router 등 많은 dependencies(의존성 모듈)가 필요하다.
  • 단방향 데이터 바인딩만 제공하는 것이 복잡도를 줄이기 때문에 장점이기도 하지만, 양방향 바인딩에 비해서 더 많은 양의 코드를 작성해야 하므로 불편할 수 있다고 한다.

 

9. 리액트의 '컴포넌트 기반 아키텍처'의 의미가 무엇인가?

  • 리액트에서 컴포넌트는 애플리케이션 UI 구축의 기반이다. 컴포넌트 기반 시스템이 구축되면, 각각의 개별적인 구성 요소들은 재사용이 가능하며 서로 독립적으로 존재한다. 즉 구성 요소 간 서로 의존하지 않으며 애플리케이션의 UI 개발이 용이해진다.

 

10. 리액트에서 렌더링이 어떻게 동작하나?

  • 리액트에서는 모든 컴포넌트가 렌더링이 되어야 하기 때문에 렌더링이 매우 중요한 부분이다. 리액트에서 렌더링은 render() 함수를 통해 이루어지는데, 이 함수가 호출되면 DOM 요소를 나타내는 요소가 반환된다.
  • 한번에 둘 이상의 HTML 요소를 렌더링하는 것도 가능하다. HTML 요소들을 여는 태그, 닫는 태그로 감싸면, 즉 enclosing tag로 감싸면 여러 요소를 동시에 렌더링할 수 있다.

 

11. 리액트에서 상태(state)란 무엇인가?

  • 리액트에서 상태는 컴포넌트의 동작 및 렌더링과 같은 부분을 제어하는 데이터 또는 객체를 의미한다.
  • 상태를 이용하여, 동적이고 인터랙티브한 컴포넌트를 쉽게 개발할 수 있다.

 

12. 리액트에서 props란 무엇인가?

  • 리액트에서 props는 프로퍼티(properties, 속성)의 줄임말로, 읽기만 가능하며(read-only) 불변성을 지닌 요소를 의미한다.
  • 애플리케이션에서 props는 부모 컴포넌트로부터 자식 컴포넌트로 전달되는 계층 구조를 따른다. 반대는 불가능하다. 리액트는 단방향 데이터 흐름 모델을 사용하기 때문이다.

 

13. 리액트에서 화살표 함수는 어떤 용도로 쓰이는가?

  • 클래스형 컴포넌트 내에서는 bind를 사용하여 this 바인딩을 따로 해주어야 한다. 하지만 화살표 함수를 사용한다면 this 바인딩을 따로 해주지 않아도 돼서 편리하다. (참고: React에서의 binding)
class Input extends Component {
  constructor() {
    // ...
    this.handleChange = this.handleChange.bind(this);
  }
  handleChange(e) {
    // ...
  }
  render() {
    return <input onChange={this.handleChange} />;
  }
}

↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓
class Input extends Component {
  handleChange = e => {
    // ...
    console.log(this);
  };
  render() {
    return <input onChange={this.handleChange} />;
  }
}
const Headline = ({ value }) => {
  return <h1>{value}</h1>;
};

↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓
const Headline = ({ value }) => <h1>{value}</h1>;

 

14. 리액트에서 HOC(고차 컴포넌트)란?

(답변 참고: https://velopert.com/3537, https://negabaro.github.io/archive/react-Higher-Order-Components)

  • 반복되는 컴포넌트 로직을 쉽게 재사용하기 위한 기술로서, 컴포넌트를 취하여 새로운 컴포넌트를 반환하는 함수를 의미한다.
  • 우선 HOC의 네이밍은 with_____ (예: withTheme) 형식으로 짓는다.
  • HOC은 컴포넌트를 인자로 전달 받는다. 그리고 전달 받은 컴포넌트를 기반으로, 전달 받은 props와 HOC 내부에서 추가적으로 생성한 props를 주입한 새로운 컴포넌트를 반환한다.
const withHOC = WrappedComponent => {
  const newProps = {
    loading: false,
  };
  return props => {
    return <WrappedComponent {...props} {...newProps} />
  }
};

.
.
.
// 이를 사용할 때는 아래와 같이 어떤 함수를 내보내줄 때 HOC으로 감싸서 내보내면 됨.
export default withHOC(AnyComponent);
  • HOC은 다음의 경우에서 사용할 수 있다.
    • 유저 인증 로직 처리 (예시 참고)
    • 로딩/에러 로직 처리
  • 이렇게 HOC을 사용하면, 비즈니스 로직과 presentational 컴포넌트를 분리할 수 있어 깔끔하다.

 

15. CRA란?

  • CRA(create-react-app)은 React의 공식 CLI(명령줄 인터페이스)로서, SPA 개발 초기 세팅을 편리하게 할 수 있도록 한다.
  • 애플리케이션을 개발할 때 create-react-app을 사용하면 개발자가 빌드 구성을 직접 하지 않아도 되기 때문에 코드에만 집중할 수 있어 효율적으로 개발을 할 수 있다.

 

복사했습니다!