React의 정의
React 공식 홈페이지에 따르면, 사용자의 인터페이스를 짓는 JavaScript library라고 설명한다.
문자 그대로 해석은 가능하지만 무언가 직접적으로 와닫지 않는다.
그렇기에 React를 사용하는 사이트들이 어떻게 동작하는가에 대해서 살펴볼 필요성이 있다.
많이들 알고있고 사용하고 있는 OTT(over-the-top) 서비스 중 하나인 Netflix를 예로 들어보자면,
처음 로그인을 하고 특정 버튼들을 눌러서 여러 상호작용이 가능하다.
이 때에 무언가를 로딩하느라 기다릴 필요도 없다.
또한, 화면 전환도 빠르며 브라우저에서 여는 웹 사이트가 모바일 앱과 같은 동작을 한다고 여길 정도로 매우 부르럽게 작동한다.
이는 기존의 웹 사이트 동작 방식과 사뭇 다른 느낌으로 다가온다.
전통적인 웹 사이트의 경우 우리가 링크나 버튼을 클릭하면 그 요청이 서버로 request되고, 새로운 html 페이지가 브라우저[client]로 response이 도착해야만 화면을 통해 볼 수 있었다. 그렇기에 약간 무겁고 불편하며 새로운 페이지가 로딩되는 동안 기다려야 했다.
위의 그림은 client와 server 간의 request와 response cycle이다.
이 시점에서는 react가 그다지 필요하지 않았다. 그저 JavaScript만을 가지고도 사용자들이 보는 것을 조작할 수 있었다.
브라우저에서 JavaScript는 DOM(Document Object Model)을 조작할 수 있는데, 이를 통해 html의 요소들이 화면에 렌더링 된다. 많은 개발자들은 사용자들이 새로운 페이지를 기다리는 로딩 시간을 없애기 위해 JavaScript로 DOM을 조작하여 사용자들이 보는 것을 변경했다.
React 역시 JavaScript 기반 library이기 때문에 기존의 JavaScript에서 추가적인 구성요소라고 생각할 수 있다.
실제로 React.js는 client 측의 JavaScript library고, JavaScrpit 코드를 작성하는 데 도움을 준다.
왜 리액트가 필요할까?
JavaScript로 충분히 구현 가능하다면 React가 굳이 필요없지 않을까? 이에 대한 해답은 아래 예제를 참고했다.
해당 예제에서는 버튼을 클릭하면 간단한 Dialog를 만드는 페이지이다. JS와 React 버전 두가지가 있으며, 그 차이를 알아보고자 한다.
// In JavaScript
const button = document.querySelector('button');
let modal;
let backdrop;
button.addEventListener('click', showModalHandler);
function showModalHandler() {
if (modal) {
return;
}
modal = document.createElement('div');
modal.className = 'modal';
const modalText = document.createElement('p');
modalText.textContent = 'Are you sure?';
const modalCancelAction = document.createElement('button');
modalCancelAction.textContent = 'Cancel';
modalCancelAction.className = 'btn btn--alt';
modalCancelAction.addEventListener('click', closeModalHandler);
const modalConfirmAction = document.createElement('button');
modalConfirmAction.textContent = 'Confirm';
modalConfirmAction.className = 'btn';
modalConfirmAction.addEventListener('click', closeModalHandler);
modal.append(modalText);
modal.append(modalCancelAction);
modal.append(modalConfirmAction);
document.body.append(modal);
backdrop = document.createElement('div');
backdrop.className = 'backdrop';
backdrop.addEventListener('click', closeModalHandler);
document.body.append(backdrop);
}
function closeModalHandler() {
modal.remove();
modal = null;
backdrop.remove();
backdrop = null;
}
우선 JavaScript의 경우 간단한 작업인데도 코드가 길어진다. 그리고 버튼이 하나가 아닌 여러 개의 동작을 설명하기 위해서는 추가적으로 많은 코드들이 작성되어야만 한다. 어떤 특정한 버튼을 활성화시켜주기 위해서는 그 버튼이 무엇인지를 알아야하며 다른 작용을 하기 위해서는 또 다른 코드가 필요하다.
또한, 모든 단계를 일일이 작성해야한다는 문제를 가지고 있다. 어떤 요소(div, p, input, ...와 같은 tag들)를 생성하고 내용을 입력하고 class나 id를 넣으며 event listener를 추가하고 싶다면 그 모든 단계들이 전부 설명되어야 한다. 이런 방식으로 화면에 불러오는 방식을 명령형 접근방식(imperative approach)
이라고 말한다. 이런 방식은 지속적으로 사용할 수는 있으나 특정 한계에 부닥치게 된다. 그리고 한계에 다다르지 않는다고 하더라도 개발자로서 이런 모든 핵심적 세부사항들을 모두 신경써야 한다. 그렇기에 계속 되풀이되는 반복적 작업으로 시간을 낭비하게 된다.
// Todo.js
import { useState } from 'react';
import Backdrop from './Backdrop';
import Modal from './Modal';
function Todo(props) {
const [showModal, setShowModal] = useState();
function showModalHandler() {
setShowModal(true);
}
function closeModalHandler() {
setShowModal(false);
}
return (
<div className='card'>
<h2>{props.text}</h2>
<div className='actions'>
<button className='btn' onClick={showModalHandler}>
Delete
</button>
</div>
{showModal && <Backdrop onClick={closeModalHandler} />}
{showModal && <Modal text='Are you sure?' onClose={closeModalHandler} />}
</div>
);
}
export default Todo;
// App.js
import Todo from './components/Todo';
function App() {
return (
<div>
<h1>My Todos</h1>
<Todo text='Learn React' />
</div>
);
}
export default App;
그러면 React 코드를 보자. JavaScript로 제작된 코드와 똑같은 방식으로 작동되지 코드는 매우 다르다. 보기에는 훨씬 복잡하고 많은 파일들을 가지고 있다. 여기서 JavaScript와 다른 특이한 점은 사용자 지정 component와 element가 있다는 것이다. React는 응용프로그램을 작은 building block과 component들로 분활하는 것에 관한 것으로 모든 building block과 component들은 명확하게 주어진 task들을 가지기에 유지 보수와 관리가 용이하다. 이러한 React에서 library는 코드를 조합해서 화면에 무언가를 렌더링하게 된다. 그러므로 개발자들은 React와 연계해서 복잡한 사용자 interface 작업을 더 쉽게 구축할 수 있게 된다. React는 고수준의 구문들을 제공하기에 JavaScript와 달리 선언형 접근방식(declarative approach)
으로 코드를 작성할 수 있다. 이미 구축해둔 component를 활용해서 사용만 하면 되는 방식으로 말이다.
React의 대안들(Vue.js, Angular)
갑자기 왜 React에 대해서 설명하다가 대안에 대해서 말을 꺼내나싶을 수 있으나 많은 개발 입문자들이 React를 정말 배워도 되나라는 고민을 할 것이다. 현재까지도 가장 인기있는 front-end framework이자 component 기반의 UI library인 React는 component에 중점을 두고 있기 때문에 내장된 다른 기능들은 많지 않다. 만약 routing이 필요하다면, 추가적인 third party library를 설치해야한다. 이와 같이 react로 작업할 때 종종 발생하는 일이다.
그렇기에 매번 추가적인 library를 설치해줘야하는 React보다는 다른 대안을 가진 framework가 생겨나기 시작했다. 그 중 하나인 Angular는 아직까지 크게 영향력이 있거나 인기가 있던 적은 없었던 front-end framework이다. Angular는 완벽하게 component 기반의 UI framework이며, 처음부터 TypeScript(type을 가진 JavaScript)를 수용했다. 너무 많은 기능들이 내장되어 있기에 작은 project에는 과할 수 있지만 대규모 프로젝트라면 말이 달라진다. framework에 이미 많은 것들이 내장되어 있기에 구글링에 많이 의존하지 않아도 될 것이다. 하지만 약간 고려해야하는 것이 있다면 문법이 다르다는 것인데 Angular는 React와 약간 다른 방식으로 component를 구축하기 때문이다.
또 다른 framework가 존재한다. 마찬가지로 아직 인기없는 Vue.js가 있다. Vue.js는 Angular와 React를 합쳐놓은 것 같이 양 극단 사이에 존재한다고 볼 수 있다. Vue.js 역시 component 기반 UI framework이며 많은 기능들을 포함하고 있지만 그 기능들은 Angular보다는 적고, React보다는 많다. 또한 routing과 같은 핵심 기능들은 포함하고 있어서 Angular와 마찬가지로 구글링에 많이 의존하지 않아도 된다. 하지만 Angular를 사용할 때만큼 과부화가 되지 않는다는 특징이 있다.
이런 식으로 front-end에 입문하고자 하는 많은 사람들은 무엇으로 공부해야하는지 고민하고 어떤 것이 trend가 될 것인지 고민하곤 한다. 그래서 나도 얼마나 많은 사람들이 관심을 가지고 있는지 알아보기 위해 Google trends에 검색해봤다.
전 세계를 통틀어 아직까지도 React를 많이 사용하고 있으며 매력이 넘치는 framework이다. 그럼에도 다른 framework에 대해 관심을 가지는 것은 React보다 다른 이점이 있다는 것은 분명하다. 무엇을 선택하라고 말하진 않겠다. 하지만 이미 조직화된 개발 환경을 전반적으로 뜯어 고치는 것은 어려울 것이며, 누군가는 유지 보수를 해야한다. 세계적인 추세나 한국에서의 사용빈도를 볼 때에 나는 React를 선택했고 아직 늦지 않았다고 생각한다. trend가 바뀌면 또 공부하면 된다는 마인드로 오늘도 공부에 임한다.