가치투자자

[React/기술면접] React란? 본문

Programming/React

[React/기술면접] React란?

미주민 2023. 6. 10. 19:30
728x90
반응형

 React란? 

* 기술면접 질문은 맨 아래에 적혀 있습니다

 

 

JavaScript만으로 큰 어플리케이션을 만들 수 있게 되면서 프론트엔드 사이드에서 돌아가는 어플리케이션 구조를 관리하기 위해 다양한 프레임워크들이 등장했다. 이 프레임워크들은 주로 모델(Model)과 뷰(View)로 구성된 아키텍처를 사용한다. 예를 들어, AngularJS의 경우에는 MVW(Model-View-Whatever) 아키텍처로 어플리케이션을 구조화했다. 여기서 모델은 앱에서 사용하는 데이터를 관리하는 영역이고, 뷰는 사용자에게 보여지는 부분이다.

 

 

따라서 데이터가 변경되면 데이터가 반영되는 부분을 찾아 수정해야 한다. 그러나 어플리케이션의 규모가 커지고 구조가 복잡해질수록 이 과정이 결코 쉽지 않다. 그래서 페이스북에서는 오직 뷰(View)만 신경쓰는 라이브러리를 만들었는데, 그것이 React다.

이제 많은 개발자들이 사용하는 React가 무엇이고, 리액트의 특징에는 어떤 것이 있는지 살펴보고자 한다.

 

 

728x90

 


 1. 가상 돔 (Virtual Dom) 

 1-1. 렌더링 과정 

React는 JavaScript 라이브러리의 하나로서 사용자 인터페이스(UI, User Interface)를 만드는 데 사용된다. 앞서 살펴본 것처럼 웹이나 앱에서 눈에 보이는 부분을 담당하는 것이다. React가 웹 페이지에서 눈에 보이는 부분을 어떻게 담당하는지 이해하기 위해 기존의 렌더링(Rendering) 과정을 살펴보자.

 

 

 

웹 브라우저는 브라우저 창에서 내용을 보여주기 위해 DOM 트리와 스타일 트리를 생성한다. 그리고 Attatchment 과정을 통해 attach 메서드로 스타일 정보를 계산하고 결과값을 객체 형태로 반환한다. 이때의 계산 과정은 모두 동기적(Synchronous)으로 동작하며, 트리에 새로운 노드가 추가된다면 해당 노드의 attach 메서드로 스타일 정보를 계산한다. 그 다음으로 Layout 과정을 통해 각 노드에 좌표를 부여하고 어디에 표시되는지 결정한다. 마지막으로 브라우저는 painting 과정을 통해 렌더링된 요소들에 색상을 입힌다.

 

만약 자바스크립트를 사용하여 DOM을 조작하게 되면 리플로우(Reflow, 레이아웃 과정의 재실행)와 리페인트(Repaint, 페인팅 과정 재실행)가 발생하는데, 이는 DOM의 각 노드에 대한 연산 과정을 다시 수행하는 것이므로 이 과정이 많이 발생할수록 웹 서비스의 성능이 떨어지게 된다. 예를 들어, To do 리스트에서 할 일을 추가할 때마다 리플로우 & 리페인트가 발생하게 된다.

 


 1-2. Reconciliation (재조정) 

React는 이 문제를 해결하기 위해 화면 상에 나타나는 Browser DOM을 직접 제어하지 않는다. 대신 실제 돔과 유사한  가상 돔(Virtual DOM) 을 만들고 이곳에서 데이터가 변경된 부분을 반영한다. 렌더링 이전에 가상 돔과 렌더링 이후에 보여줄 가상 돔 2개를 생성하고, 두 가상 돔을 비교하는 과정(Diffing 과정)을 거쳐 바뀐 곳을 찾는다. 그리고 변경된 곳의 요소(element)를 새로 "갈아끼우는" 재조정 과정(reconciliation)을 거친다. 즉, 기존의 요소에 변경 사항을 업데이트 하는 것이 아니라, 요소를 통째로 바꿔치기 한다. 따라서 변경된 요소만 계산하여 바꿔주면 되기에 리플로우와 리페인트를 최소화할 수 있고, 렌더링 속도도 빨라지게 된다.

 

Reconciliation

 

 


 2. JSX 

그렇다면 React에서는 UI를 어떻게 만들까?

순수 자바스크립트만으로 코드를 구현할 경우에는 아래처럼 HTML로 구현하며, 이때는 JS 코드가 필요하지 않다.

<h1>환영합니다!</h1>

 

반면 React에서는 JSX를 통해 UI를 구축한다.

 JSX 는 A Syntax Extension to JavaScript의 줄임말로, 자바스크립트의 확장 문법을 말한다. 즉, HTML만으로 UI를 만드는 것이 아니라, XML/HTML와 JavaScript가 결합된 문법을 사용한다. 아래의 코드를 보면, element라는 변수에 HTML 코드가 할당되어 있다는 것을 알 수 있다.

const element = (
  <h1>환영합니다!</h1>
);

 

React에 익숙하지 않은 사람이 이 코드를 보면 이해하기 어려울 수 있다.

그러나 사실 JSX는 HTML 코드가 JavaScript 코드로 변환되어 나오기에 브라우저가 이 문법을 이해할 수 있다. 이때 React는 createElement() 함수를 사용해 JSX를 자바스크립트 코드로 변환해준다. createElement의 1번째 인자에는 타입(type), 2번째 인자에는 속성들(props), 3번째 인자에는 자식 엘리먼트들이 들어간다.

React.createElement(
  type,
  [props],
  [...children]
);

아래의 예시를 보면, 우리는 JSX 코드를 짰지만, React는 이를 createElement 함수를 통해 JSX 코드를 자바스크립트 객체로 변환해준다. React는 이 객체를 읽어서 DOM을 만들어준다.

/* JSX를 사용한 코드 */
const element = (
  <h1 className="greeting">환영합니다!</h1>
);

/* JSX를 사용하지 않은 코드 */
const element = React.createElement(
  'h1',
  { className: "greeting" },
  '환영합니다!'
);

/* 자바스크립트 코드로 변환된 결과물 */
const element = {
  type: 'h1',
  props: {
    className: 'greeting',
    children: '환영합니다!'
  }
};

 


 2-1. JSX의 장점 

1) 간결한 코드

createElement 함수를 활용해 element를 만들수도 있지만, 그것보다는 JSX 코드가 훨씬 간결하고 가독성이 좋다. 이로 인해 버그를 발견하기 용이해진다.

/* JSX를 사용한 코드 */
const element = <h1 className="greeting">환영합니다!</h1>;


/* JSX를 사용하지 않은 코드 */
const element = React.createElement(
  'h1',
  { className: "greeting" },
  '환영합니다!'
);

 

2) 생산성 향상

순수 자바스크립트로에서는 UI를 구성하는 HTML과 기능을 구현하는 자바스크립트가 분리되어 있다. 그렇기에 어플리케이션의 규모가 커지고 기능이 많아질수록 코드를 관리하기 어렵다.

그러나 React에서는 JSX를 통해 HTML과 JavaScript 코드를 한번에 관리할 수 있다.

function App() {
  function Access() {
    ...
  }

  return (
    <div>
      <h1>환영합니다!</h1>
      <button>접속 버튼</button>
    </div>
  )
};

 

 


 3. 컴포넌트 

지금까지 UI를 구성할 element를 쉽게 만들 수 있는 JSX에 대해 살펴봤다. 그렇다면 이러한 element를 계속해서 생산해낼 수 있을까?

React에는 element를 찍어낼 수 있는 붕어빵 틀 컴포넌트(Component) 라는 것이 있다. 만약 To Do List에서 오늘 할 일(element)을 추가하고 싶을 때 새로운 element를 찍어내줄 컴포넌트가 필요하다. 또한, 필요한 곳에서 컴포넌트를 재사용할 수 있다. 만약 상단 메뉴를 하나의 컴포넌트로 만들었다면, 이를 여러 페이지에서 재사용할 수 있다.

이처럼 컴포넌트는 기능 단위, UI 단위로 캡슐화하여 코드를 관리하기에 계속해서 재사용이 가능한 독립된 모듈이다.

 

아래에는 타이틀명(title)에 따라 상단 메뉴를 만들어주는 컴포넌트다.

/* 상단 메뉴 컴포넌트 */
import React from 'react';

const Navbar = ({ title }) => {
  return (
    <nav>
      <h1>{title}</h1>
      <ul>
        <li>Home</li>
        <li>About</li>
        <li>Contact</li>
      </ul>
    </nav>
  );
};

export default Navbar;

 

우리는 이 컴포넌트를 가져와(import) 원하는 곳에서 재사용할 수 있다. 이때 컴포넌트의 이름은 대문자로 시작해야 한다.

만약 소문자로 <button /> 컴포넌트를 만들 경우, 이를 컴포넌트가 아닌 DOM 태그로 인식하게 되기 때문이다.

import React from 'react';
import Navbar from './Navbar';

const App = () => {
  return (
    <div>
      <Navbar title="My Website" />
    </div>
  );
};

export default App;

 


 3-1. 함수형 컴포넌트 vs 클래스형 컴포넌트 

컴포넌트를 선언하는 방식에는 함수형 컴포넌트(Function Component)와 클래스형 컴포넌트(Class Component)가 있다.

 

먼저,  함수형 컴포넌트 는 JavaScript 함수를 사용하여 컴포넌트를 정의한다.

초창기에는 state를 관리하지 못한다는 단점 때문에 잘 사용되지 않았지만, React 16.8 버전부터 Hooks라는 기능이 state를 관리할 수 있도록 해주면서 자주 사용되고 있다. State(상태)는 뒤에서 자세히 다루겠지만, 간단하게 말해 컴포넌트가 렌더링되었을 때 결과물에 영향을 주는 저장된 데이터를 말한다. 또한, 코드도 좀 더 간단하고, 메모리 자원도 클래스형 컴포넌트보다 덜 사용한다.

function Greeting(name) {
  return <div>안녕, 난 {name}라고 해!</div>
}

 

다음으로,  클래스형 컴포넌트 는 클래스를 사용하여 컴포넌트를 정의한다.

클래스형 컴포넌트에서는 React.component를 상속받아 컴포넌트를 만들어준다. 클래스형 컴포넌트에서는 this를 통해 state를 관리해준다. 그러나 함수형 컴포넌트에 비해 코드가 복잡하고, this를 통해 state를 괸리하다보니 환경에 따라 this가 의미하는 값이 달라진다는 단점 때문에 코드의 불확실성이 높다.

class Greeting extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      name: "홍길동"
    };

  render() {
    return <div>안녕, 난 {this.state.name}라고 해!</div>
  }
}

 

state에 대해선 아래 글을 참고하길 바란다.

 

[React/기술면접] State와 Props

State와 Props * 기술면접 질문은 맨 아래에 적혀 있습니다 웹 브라우저에서 데이터가 변경되었을 때 어떻게 반영될까? 자바스크립트에서는 DOM에 직접 접근하여 데이터 변경사항을 반영한다. 아래

valueengine.tistory.com

 


 4. 요약 

1. React 정의

  • 사용자 인터페이스(UI)를 만들기 위한 JavaScript 라이브러리

2. React 특징

1) React의 내부 작동 원리 : Reconciliation

 

  • React는 리플로우와 리페인팅 과정을 최소화하기 위해 가상 돔을 생성하고, 기존의 돔과 비교하여 변경된 요소만 갈아끼우는 재조정(Reconciliation)을 거쳐 번경 사항을 반영한다.

2) JSX

 

  • 자바스크립트 코드를 HTML처럼 표현할 수 있는 자바스크립트의 확장 문법

  • 장점

    1. 간결한 코드
    2. 생산성 향상

 

3) 컴포넌트

 

  • 기능 단위, UI 단위로 코드를 캡슐화하여 관리하기 위해 만드는 재사용이 가능한 독립된 모듈

  • 함수형 vs 클래스형 컴포넌트

    1. 함수형 컴포넌트

      : JavaScript 함수를 사용하여 정의한 컴포넌트로, 클래스형 컴포넌트에 비해 코드가 간단하다. 초창기에는 클래스형 컴포넌트에서만 state를 관리할 수 있었지만, Hooks이 등장하면서 state를 관리할 수 있게 되었고, 이로 인해 코드가 더 간결한 함수형 컴포넌트로 대체되었다.

    2. 클래스형 컴포넌트

      : class를 활용하여 정의한 컴포넌트로, React.component에서 상속받아 컴포넌트를 만들어준다. React 초창기에는 state를 관리할 수 있어 자주 사용되었지만, 함수형 컴포넌트에 비해 코드가 복잡하고, this를 통해 state를 괸리하다보니 환경에 따라 this가 의미하는 값이 달라진다는 단점 때문에 코드의 불확실성이 높다.

 

반응형

 


🌟 React 기술면접 질문

1. React의 내부 작동 원리를 설명하세요.

 

  React에서는 변경 사항이 발생할 때마다 직접적으로 실제 DOM을 제어하지 않고, 가상 돔을 통해 변경 사항이 반영되도록 작동한다. React는 렌더링 이전의 가상 돔과 렌더링 이후에 보이게 될 가상 돔 2개를 가지는데, 두 가상 돔을 비교하여 렌더링 이전의 가상 돔과 어떤 점이 달라졌는지 찾아낸다. 그리고 변경된 요소를 통째로 갈아끼워주는 재조정(reconciliation) 과정을 거쳐 바뀐 내용만 브라우저 창에 적용시켜준다. 따라서 변경된 요소만 계산하여 바꿔주면 되기에 리플로우와 리페인트를 최소화할 수 있고, 렌더링 속도도 빨라지게 된다.

 

 

2. 클래스형 컴포넌트에서 함수형 컴포넌트로 전환된 이유를 설명하세오.

 

  React 초창기에는 클래스형 컴포넌트에서만 state를 관리할 수 있었지만, this를 통해 state를 괸리하다보니 환경에 따라 this가 의미하는 값이 달라진다는 단점과 여러 단계의 상속으로 이루어져 있었기에 코드가 복잡하고 코드의 불확실성도 높았다. 그러나 Hooks이 등장하면서 함수형 컴포넌트에서도 useState와 useEffect라는 hook으로 state 로직을 재사용할 수 있게 되면서 좀 더 코드가 간결한 함수형 컴포넌트로 전환되게 되었다.

 

 


</> 끊임없이 성장하기 위해 공부한 내용을 글로 작성하고 있습니다. 틀린 부분이나 추가해야 할 부분이 있다면 언제든 댓글로 남겨주세요❗️

 


References

 

 

728x90
반응형

'Programming > React' 카테고리의 다른 글

[React/기술면접] Hook (2)  (0) 2023.07.10
[React/기술면접] Hook (1)  (1) 2023.07.09
[React/기술면접] 생명 주기 (Life Cycle)  (0) 2023.07.03
[React/기술면접] ref란?  (0) 2023.07.01
[React/기술면접] State와 Props  (1) 2023.06.13