본문 바로가기
  • soldonii's devlog
Javascript 공부/React

리액트의 탄생배경과 핵심 개념

by soldonii 2019. 11. 20.

*Udemy의"Complete React Developer in 2020"강의에서 학습한 내용을 정리한 포스팅입니다.

*자바스크립트와 리액트를 배우는 단계라 오류가 있을 수 있습니다. 틀린 내용은 댓글로 말씀해주시면 수정하겠습니다. 감사합니다. :)


1. 리액트의 탄생 배경

리액트의 등장 이전에도 프론트엔드 단에 수 많은 라이브러리/프레임워크가 존재했다.(jQuery, Vue.js, Angular.js 등) 제이쿼리의 경우, 여러 종류의 웹브라우저들마다 자바스크립트를 불러오는 방식이 달라 어려웠던 점을 해결해주었다. 브라우저들 간에 통일성을 가지도록 도와주면서 큰 인기를 끌었었다.

 

시간이 흐르면서 web app의 크기가 커지자, 자바스크립트 파일이 넘쳐나면서 통제가 어려워졌고, 이를 효율적으로 관리하기 위해 backbone.js 같은 라이브러리가 등장하면서 자바스크립트 파일의 조직적 관리가 용이해졌다. 그러면서 HTML, CSS, Javascript에서 자바스크립트의 중요성이 점점 더 커지기 시작했고, 그러면서 Single Page Application이 등장했다.

# Single Page Application

전통적으로 웹 페이지는 모든 페이지마다 HTML, CSS, Javascript 파일을 각기 가지고 있어야 했고, 따라서 페이지 간 이동을 할 때마다 HTML, CSS, Javascript 파일을 서버와 주고받았기 때문에 속도가 느릴 수 밖에 없었다. Single Page Application은 HTML, CSS, Javascript 파일을 최초 1회만 로드하고, 이후에는 자바스크립트 파일을 통해 DOM 또는 필요한 HTML 파일을 조작하는 방식을 취한다.

# Angular.js

이후 구글에 의해 Angular.js 프레임워크가 등장했다. 앵귤러는 작은 컨테이너들이 모여 거대한 앱을 구성하도록 설계된 프레임워크이다. 하지만 앱이 점점 커지고 사용자가 늘어날수록 홈페이지 내에서 user interaction이 기하급수적으로 증가하는데, 복잡성이 증가할수록 데이터의 흐름이 어디로 이어지는지 파악하기가 너무 어려웠고, 디버깅도 어려워지는 문제가 야기됐다.

# React의 등장

페이스북도 유사한 문제를 가지고 있었고, 따라서 코드베이스를 업그레이드 시킬 필요성을 느껴 개발한 것이 리액트이다. 리액트는 위에서 말한 문제들에 기반해서 개발된 라이브러리이기 때문에, 데이터가 어디서 어디로 흐르는지 명확히 알 수 있는 장점을 가지면서 선풍적인 인기를 끌었고, 현재도 큰 인기를 구가하고 있다.

 

2. 리액트의 핵심 개념

1) DOM은 내가 책임질게! - 가상 DOM(Virtual DOM)

프론트엔드에서 DOM을 조작하는 전통적인 방식은 Imperative했다. Imperative는 DOM에 보여지길 원하는 모든 요소들을 하나 하나 정확하게 명령하는 것을 의미한다. 모든 단계를 하나하나 지정해주는 것이 명확하기는 하지만, 다양한 유저 이벤트와 edge case에서 각각의 변화가 서로 어떤 연관성을 가지는지 파악하기가 어렵다는 문제가 있다.

 

사실 DOM 조작은 성능에 병목을 일으키는 요인 중 하나이다. DOM 변경은 ① 변경되어야 하는 요소들 페이지에 다시 칠하는 과정(repaint)과 ② 모든 요소들을 다시 레이아웃을 계산하여 화면에 위치시키는 작업(refloat)이 수반되기 때문에 꽤 복잡한 일이다.

 

반면 리액트는 Declarative하다. DOM 조작은 React-DOM 라이브러리가 알아서 할 테니, 화면이 어떻게 보여지기를 원하는지를 알려주는 방식이다. 예를 들어, 화면에 보여지기를 원하는 state(state는 아주 간단히 말하면 자바스크립트 객체이다)가 청사진이 되고, 이 청사진에 의거하여 리액트가 DOM을 조작해서 화면에 구현하는 것이다. Imperative, Declartive 반드시 무엇이 낫다고 할 수는 없으나, 리액트가 채택한 패러다임으로 인해 데이터의 흐름 방향 및 요소들 간의 연관성을 파악하기가 더욱 쉬워져, 코드의 복잡성은 줄어들고 코드 퀄리티는 올라가게 되었다.

 

2) 웹사이트를 레고블록들의 모음들처럼! - Component 컨셉

리액트는 재사용이 가능한 컴포넌트를 만들고, 이 컴포넌트들이 모여 웹사이트를 구성하게 된다. 이 컴포넌트들은 결국 자바스크립트 함수(또는 객체)이다. state를 세팅하고, 이를 기반으로 화면에 어떻게 보여지기를 원하는지를 작성하여 하나의 컴포넌트를 구성한다. 

 

이후 리액트에 내장된 Component 라이브러리의 기능을 불러온 후, 여기에 내장된 render() 메소드를 통해 ReactDOM 라이브러리에게 rendering될 컴포넌트를 전달하여 최종적으로 ReactDOM 라이브러리가 현재 DOM과 전달받은 컴포넌트를 비교하여 변경이 필요한 부분만 변화를 주어 화면에 보여주게 된다.

 

리액트의 컴포넌트

 

// ① 화면에 보여지길 원하는 state를
let state = {
  user: 'hyunsol do',
  isLoggedIn: True,
  friends: ['gretta', 'soldonii', 'doniisol']
}

// ② 자바스크립트 함수를 이용해서 component로 구성한다!
function Welcome(props) {
  return <h1>Hello, {props.name}</h1>;
}

// ③ 또는 이렇게 class로 만들 수도 있다.
class Welcome extends React.Components {
  render() {
  	return <h1>Hello, {props.name}</h1>;
  }
}

 

3) 일방향적인 데이터 흐름 - One Way(Unidirectional) Data Flow

리액트에서 state와 자바스크립트 코드로 구성된 component는 HTML처럼 보이는 코드를 작성할 수 있도록 구성된 JSX 문법을 기반으로 한다.

 

가상DOM은 실제 DOM과 유사하게 나무 구조로 된 자바스크립트 객체이다. 가상DOM과 실제 DOM의 비교는 자바스크립트 객체인 state로부터 시작되어, state를 기반으로 컴포넌트가 구성되고, 컴포넌트를 기반으로 가상 DOM을 그린후, 가상 DOM과 실제 DOM을 비교해 화면에 그리는 과정을 거치는데 이렇게 [ state ⇒ component ⇒ 가상 DOM ⇒ 실제 DOM과 비교 ⇒ 화면에 그리기 ] 과정이 일방향적으로 이루어진다.

 

일방향적인 데이터 흐름1

 

이처럼 데이터의 흐름이 위에서 아래로, state에서 실제 화면으로, 즉 one-way로 제한되기 때문에 디버깅이 편리해진다. Angular를 비롯한 기존 Single Page Application의 복잡성으로 인한 데이터 흐름 추적의 어려움을 상당 부분 해결할 수 있는 방식이다.

 

일방향적인 데이터 흐름2

 

4) 리액트는 UI에 불과하다. 나머지는 전적으로 내게 달려있다.

리액트 이전 Angular.js의 경우, 앱을 만드는데 필요한 모든 것이 갖춰진 프레임워크였다. 오븐, 도마, 스토브 등 모든 것이 갖춰진 주방에 비유할 수 있다. 반면 리액트는 UI 라이브러리이다. 화면이 어떻게 보여질지만 도움을 주고, 그 외 모든 것들은 알아서 처리해야 한다. 앵귤러가 주방이라면 리액트는 오븐에 비유할 수 있다. 오븐 외에 칼, 도마, 그릇, 재료 등은 내가 알아서 선택해서 요리를 완성해야 한다.

 

이러한 특성 때문에, 리액트를 다른 분야에서도 활용할 수 있다. 리액트 라이브러리를 그대로 ReactDOM 라이브러리 대신 ReactNative 라이브러리와 결합시키면 앱을 만들 수 있으며, React360 라이브러리와 결합시키면 VR을, ReactElectron과 결합시키면 데스크톱 앱을 만들 수 있다. 따라서 자바스크립트를 기반으로 모바일, VR, 데스크톱 어떤 것이든 만들 수 있는 크로스 플랫폼 역할을 한다.

 

3. 훌륭한 리액트 개발자란?

아래 내용은 지금 알 필요도 없고, 원론적인 이야기지만 이정표처럼 보기 위해 정리한다.

1) 컴포넌트에 대한 뛰어난 의사 결정

컴포넌트를 얼마나 작은 단위로 쪼갤 것인지, 어떻게 재사용 가능한 컴포넌트를 만들 것인지 아는 개발자.

2) state가 존재하는 위치에 대한 의사 결정

state는 가상 DOM 내에 여러 곳에 존재할 수 있는데, 이를 어디에 위치시킬지 아는 개발자.

3) state가 변경될 때, 컴포넌트에 어떤 변화를 줄 것인지에 대한 의사 결정

state가 변경되었을 때, 어떤 부분이 re-rendering 되어야 하는지 아는 개발자.

댓글