질문 출처: 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. 리액트의 주요 특징
- 리액트는 단방향식 데이터 흐름 모델을 사용한다. (참고: "데이터는 아래로 흐릅니다")
- 리액트는 가상 DOM을 사용한다.
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} />;
}
}
- 함수형 컴포넌트를 정의할 때도 화살표 함수를 사용하면 좀 더 간결한 코드를 작성할 수 있다. (참고: https://www.robinwieruch.de/react-function-component/)
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을 사용하면 개발자가 빌드 구성을 직접 하지 않아도 되기 때문에 코드에만 집중할 수 있어 효율적으로 개발을 할 수 있다.
'학습 내용 > Front-End' 카테고리의 다른 글
[Next.js] Next.js의 프리 렌더링(pre-rendering) 옵션 3가지 / SSG, SSR, ISR (0) | 2022.06.01 |
---|---|
Luhn algorithm(룬 알고리즘)으로 유효한 카드 번호인지 확인하기 (0) | 2022.05.10 |
Safari에만 적용되는 코드를 짜고 싶다면? (0) | 2021.10.06 |
[Next.js] Next.js에서 CSS 사용하기 (0) | 2021.10.03 |
[React] 리액트 상태 관리의 과거, 현재, 그리고 미래 (0) | 2021.09.29 |