🎄사실 이건 정말 대답하기 힘든 질문이다.
"리액트를 사용하는 이유는 무엇일까요?"
이 질문은 꽤나 대답하기 어렵습니다.
왜일까요?
이렇게 대답할 수도 있을 것 같습니다.
모두가 리액트를 쓰니까 저도 쓰는거죠!!
어...나도 그렇기는 한데..
어떻게 보면 유명한 걸로 유명한 연예인같은 느낌이 들기도합니다.
물론 그럼에도 불구하고 리액트가 많은 사람들의 사랑을 받은 이유는 이야기할 수 있을 것입니다.
이번에는 그런 "그럼에도 불구하고"에 초점을 맞추어
왜 나는 리액트를 사용하는 시대에 살고 있을까? 라는 질문에 대한 답을 찾아보겠습니다.
리액트가 많은 사랑을 받을 수 있었던 요인을 알아보기 위해서는
리액트가 기존 웹의 어떤 문제를 해결했는지에 집중할 필요성이 있습니다.
리액트가 나오기 전인 2012년 이전의 세계로 돌아가봅시다.
이때에는 vue는 존재하지 않았습니다. vue의 출시는 2014년 2월이네요.
앵귤러는 앵귤러의 전신 AngularJS 라는 이름으로 존재하고 있었습니다.
AngularJS 의 출시일은 2010년 10월 20일이네요
참고로 리액트는 2013년 5월 29일에 최초 출시되었다고 합니다.
그리고 놀랍게도 let / const , 화살표 함수, 클래스 , 프로미스 , ESM 등 우리에겐 너무 익숙한
ES6 문법은 2015년이 되어서야 등장합니다.
ES6는 (ECMA Script 2015) 로도 불려요!
그럼 모던 프론트엔드 개발을 가능하게 해준 웹팩과 바벨은 어떨까요?
웹팩의 출시 년도는 2012년 3월 10일
바벨은 2014년 9월 28일 입니다.
번들러와 모듈시스템에 관해서는 아주 재미있게 정리 된 짤도 존재하죠!
그리고 이후 번들러는 발전의 발전을 거듭하며
HMR(Hot Mudule Replace)라는 너무 혁신적인 기능도 개발되었고
프론트엔드 개발은 근 10년 새에 눈부시게 발전해왔습니다.
그리고 이 근 10년의 세월 동안 리액트는 기존에 많이 사용되던 제이쿼리를 밀어내고
앵귤러 , 뷰를 제치며 독보적인 입지를 구축하게 되었습니다.
이야기가 조금 많이 샌 것 같기도하지만 다시 본론으로 돌아와봅시다.
리액트가 등장하기 이전 사람들은 제이쿼리를 사용했습니다.
제이쿼리는 어떤 문제를 해결해주었을까요?
😒제이쿼리는 어떤 문제를 해결했을까?
제이쿼리는 2006년 8월 26일에 최초 출시된 라이브러리입니다.
이 제이쿼리는 무엇을 해결해주었을까요?
바닐라 자바스크립트부터 차근차근 코딩을 시작하신 분들이라면 공감하실 것 같은 문제가 하나 있습니다.
그 문제를 쉽게 이해하기 위해 비슷한 일을 수행하는 리액트 코드와 자바스크립트 코드를 비교해봅시다.
const DSA = ({}: DSAProps) => {
const [counter, setCounter] = React.useState(0);
const increase = (state: number) => state + 1;
const onClick = () => setCounter(increase);
return (
<div>
<div>{counter}</div>
<button onClick={onClick}>더하기 버튼</button>
</div>
);
};
눌렀을때 값을 증가시키는 일을 수행하는 React 코드입니다.
이제 바닐라 자바스크립트로 작성한 경우를 생각해볼까요?
const button = document.querySelector('#increase-button');
const showCounter = document.querySelector('show-counter');
let counter = 0;
const increase = (state) => state + 1;
const updateView = () => {
showCounter.textContent = counter;
};
const buttonHandler = () => {
increase(counter);
updateView();
};
button.addEventListener('click', buttonHandler);
심지어 이 코드는 html은 이미 작성되어 있다는 가정하에 이렇게 작성되었습니다.
만약 html 요소들을 자바스크립트를 이용해서 생성해야한다면 여기에 더 많은 코드가 필요할 것입니다.
"리액트 스럽게" 동작하게 하기 위해 디스패처같은것들을 만들어 쓴다면 더욱 길어지겠죠
이와 같이 바닐라 자바스크립트의 세계에서는
1. 내가 원하는 HTML 요소를 셀렉팅 해와야한다. document.querySelector()와 같은 것을 이용해서
2. 상태를 컨트롤할 함수를 만들어야 한다.
3. 필요하다면 DOM Element를 직접 생성해야한다.
4. 이벤트가 일어났을때 어떤 행동을 취하게 하기 위해서는 addEventListener를 통해 이벤트핸들러를 붙여준다.
5. 2번 함수로 인해 바뀐 상태는 개발자가 직접 화면에 업데이트 해준다.
그 과정에서 생소한 문법들을 외워야하는 부분도 큽니다.
처음 개발하는 입장에서 document.querySelector, addEventListener , appendChild, textContent, setAttribute
이런 메서드들을 모두 꿰고 있어야지만 원하는 동작을 구현할 수 있고
그 과정에서 길고 긴 상용구들을 계속해서 작성해야만 합니다.
거기에 더불어 우리는 아직 ajax를 고려하지 않았습니다.
ajax의 시대가 열리며 서버로부터 받아온 데이터를 자바스크립트를 이용하여
동적으로 요소들을 생성하고 적절하게 보여주어야하는 소요도 생기게되었습니다.
그런데 ajax를 빼놓고 코드를 작성해도 힘든 작업에 ajax까지 곁들이면 더욱 코드짜기가 힘들었을 것입니다.
제이쿼리는 바로 이 pain point를 해결해줍니다.
<!DOCTYPE html>
<html>
<head>
<title>jQuery DSA Example</title>
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
</head>
<body>
<div id="root"></div>
<script>
$(document).ready(function() {
let counter = 0;
function increase(state) {
return state + 1;
}
function updateCounter() {
$('#counter').text(counter);
}
function onClick() {
counter = increase(counter);
updateCounter();
}
const counterDiv = $('<div>', { id: 'counter', text: counter });
const button = $('<button>', { text: '더하기 버튼' });
button.on('click', onClick);
const container = $('<div>').append(counterDiv, button);
$('#root').append(container);
});
</script>
</body>
</html>
이 제이쿼리 코드는 HTML 요소를 동적으로 생성하고 화면에 보이게하는 것까지를 담당합니다.
뜻은 모르더라도 한결 코드의 양이 줄어들고 읽기 쉬워진것을 알 수 있죠?
이러한 제이쿼리의 등장으로 인해 개발자들은 거지같은 자바스크립트를
조금 더 편안하게 사용할 수 있어졌습니다.
정말 행복한 일이 아닐 수 없네요!!
😑하지만 제이쿼리도... 아니야
이렇듯 행복을 가져다준 제이쿼리였지만 이 역시도 여전한 불편함이 있습니다.
코드가 간결해졌어도 여전히 제이쿼리는 기존 자바스크립트와 동일한 문제를 공유합니다.
바로 개발자가 모든 것을 일일히 알려주어야하는
"명령형 프로그래밍"이 강요된다는 것이에요!
여전히 제이쿼리는 데이터를 변경할 때마다 DOM을 조작해주어야했고
요소들을 명시적으로 셀렉팅해야했으며 이벤트를 직접 연결해주고
돔조작을 최소화 하기 위해 컨테이너 혹은 프래그먼트를 만들고
그 컨테이너에 모든 요소들을 달아준 뒤 컨테이너를 붙여주는 일도 직접 해야했습니다.
그리고 구글의 앵귤러js를 기점으로 템플릿 , 데이터 바인딩에 대한 개념이 등장합니다.
또 한편으로는 ajax의 시대가 열리면서 DOM 조작이 잦아지고
웹이 발전하며 유저간 상호작용도 많아지는 형태가 되었는데
상호작용을 위해 DOM 을 직접 조작하는 것은
상당히 큰 비용이 드는 일이었다는 것입니다.
DOM Node들은 수많은 상속관계를 가지고 있고 그 자체로 꽤나 무거운 객체입니다.
또한 DOM 을 직접적으로 조작하게 되면 reflow, repaint 과정을 거치며
브라우저는 적절한 화면을 다시 그려주기 위해 연산을 수행하게됩니다.
당연히 DOM 조작이 잦을 수록 연산도 잦아집니다.
무거운 연산이 잦아지면 성능에 영향이 갑니다.
이렇듯 DOM 조작은 꽤나 무거운 비용을 요구하는 행위였다는 것이 문제였습니다.
즉 요약하자면 제이쿼리 시대의 문제는 다음과 같았습니다.
1. DOM을 직접 조작하는 것은 자칫하면 큰 성능 문제를 불러온다.
2. 명령적인 프로그래밍 방식은 너무 힘이 들고 실수하기 쉽다.
이 이후는 모두가 알다시피 선언적 프로그래밍과 MVVM 아키텍처를 기반으로
눈부신 발전을 이루며 리액트, vue , angular가 성장합니다.
이것은 리액트 공식문서에서 설명하는 리액트의 특징입니다.
리액트는 데이터 변경에 따라 적절한 컴포넌트만 효율적으로 갱신하고 렌더링해줍니다.
즉 제이쿼리의 시대까지 우리가 해왔던
데이터 변경 -> 변경된 데이터와 view의 동기화
과정을 대신 수행해준다는 것이지요
이 과정에서 양방향 바인딩을 따르는 앵귤러, 뷰와 단방향 바인딩을 따르는 리액트
프레임워크에 가까운 형태를 띄는 앵귤러,vue 라이브러리에 가까운 리액트 등
세부적인 차이가 존재했지만 결국 이루어주는 대전제는 비슷했습니다.
선언적으로 뷰를 만들 수 있게 되었다는 것입니다.
거기다가 DOM 직접 조작으로 인한 성능 문제를 걱정하지 않아도 되도록
Virtual DOM이라는 개념을 도입하며 개발자들이
"보여줄 화면"에 더 집중할 수 있는 환경을 구성해주었습니다.
🤗React 의 Virtual DOM은 성능이 좋나요?
그렇다고해서 React의 Virtual DOM의 성능이 엄청나게 뛰어난 것은 아닙니다.
Virtual DOM은 Real DOM의 경량화 버전으로서 작은 크기의 엘리먼트들로 관리되고 있지만
애초에 Virtual DOM을 생성하고 관리하는 것 자체가 비용이니까요
심지어 리액트는 이 버츄얼 돔을 두벌로 관리합니다.
기존 DOM 개체의 복사본 한개와 / 상태 업데이트가 있을 때 생성되는 virtual DOM
총 두벌로 상태를 관리해요
위 사진은 solid.js에서 제공하는 퍼포먼스 표입니다.
vanila javascript를 1로본다면 리액트는 거의 2에 가까울 정도로 성능차이가 심합니다.
반면 바닐라 자바스크립트와 거의 성능이 비슷한 프레임워크
solid.js와 svelte는 대표적으로 버츄얼돔을 채택하지 않은 프레임워크들입니다.
버츄얼돔을 포기하면 더 빠른 , 더 좋은 성능을 얻을 수 있다는 것을 두 프레임워크들이 보여줍니다.
This completely different implementation forgoes a Virtual DOM.
solid.js는 공식문서에서도 가상 DOM을 포기했다고 명시합니다 하하;;
그럼에도 불구하고 리액트는 왜 Virtual DOM을 선택했을까요?
리액트팀은 Virtual DOM 을 사용해도 "충분히 빠르기 때문"에 Virtual DOM의 성능을 어느정도 용인한다고
(어딘가에서 본 기억이 있습니다... ㅎㅎ;;)
virtual DOM을 선택함으로서 잃게되는 성능보다
virtual DOM을 선택함으로서 얻을 수 있는 이득이 더 크다고 판단한것이지요
리액트의 성능과 관련해서 더 많은 흥미로운 사실들이 궁금하다면
https://ktseo41.github.io/blog/log/things-you-forgot-or-never-knew-because-of-react.html
리액트로 인해 잊었거나 전혀 몰랐던 것들이라는 아티클을 읽어보시는 걸 추천드립니다.
🤩그럼 왜 우리는 모두 리액트를 쓸까? (결론)
angular는 타입스크립트와 데코레이터, 객체지향 개념을 적극 차용하며
악랄한 러닝커브를 보여주었습니다. vue는 나름의 인기를 끌었지만
리액트는 Hot Module Replace, SSR, SEO 등
다른 프레임워크가 해결하지 못한 새로운 영역들을 선점해나가며
점유율을 계속 끌어올렸고
특정하기 힘든 어느 시점부터는 많이 쓰니까 많이 공부하게되며
프론트엔드 생태계를 리액트가 거의 하나로 통합했기 때문에
우리는 리액트를 사용한다. 라고 할 수 있을 것 같습니다.
사실 리액트는 더이상 새롭지도, 빠르지도 않은 라이브러리입니다.
그러나 그와 동시에 정말 많은 사람들이 사용하는 라이브러리이기도 하지요
스벨트, 솔리드 등의 프레임워크 혹은 웹 컴포넌트로 대세가 넘어가고
리액트는 마치 제이쿼리처럼 구시대의 유물로 남는 날도 올까요?
온다면 그건 언제가 될까요?
그건 아무도 모르지 않을까 싶지만 이러나 저러나
적어도 지금 우리는 모두 리액트를 사용하고 있네요!
🥰레퍼런스
https://velog.io/@teo/MVI-Architecture
https://blog.greenroots.info/reactjs-virtual-dom-and-reconciliation-explain-like-im-five
'react' 카테고리의 다른 글
리액트 타이핑효과 커스텀 훅 만들기 (0) | 2023.08.15 |
---|---|
what is react server components 이..이거 뭐냐? (2) | 2023.08.07 |
reactquery useQuery 자동 가져오기 막는 법 (0) | 2023.07.31 |
react-error-boundary 라이브러리로 에러처리하기 (0) | 2023.07.20 |
react-query의 onError는 Deprecated 되었다. (0) | 2023.07.12 |