React를 검색하면 SPA, Virtual DOM, Hook ... 등등 단어들이 따라오는데 이번 글에서 이것들을 한번에 정리하고자한다.
SPA
Single Page Aplication의 약자로 서버로 부터 완전한 새로운 페이지를 불러오지 않고 현재의 페이지를 동적으로 다시 작성함으로써 사용자와 소통하는 웹 어플리케이션이나 웹 사이트를 말한다.
기존 전통적인 웹방식은 새로운 페이지를 요청할 때 마다 정적 리소스(CSS, 이미지, 영상...)가 다운로드 되고 전체 페이지를 다시 렌더링하는 방식이었다. 하지만 이런 방식은 규모가 커지면서 불필요한 트래픽이 증가하고 속도가 많이 느렸다.
위에서 React는 UI를 만들기 위해서 사용한다고 했는데 정확히는 SPA UI를 만들기 위해서 사용하는 것이다.
React는 경로에 따라서 다른 뷰를 보여줄 수 있다. 하지만 여기서 Header, Footer, Navbar 과 같이 공통적으로 보여지는 부분이 있을 것이다. 경로가 바뀌어도 공통적으로 가지고 있는 컴포넌트들은 다시 요청하기 보다는 그대로 유지하고 변경되는 부분만 요청해서 불러오는 것이 좋다.
Virtual DOM
Virtual DOM은 DOM과 유사한 객체를 메모리에 올려 변경사항이 있으면 현재 DOM과 비교하여 변경된 부분만 실제 DOM에 적용시킬 수 있게 해주는 추상화 된 DOM이다.
실제 DOM을 조작하게 되면 레이아웃을 다시 계산하고 그려야하기 때문에 비용이 높은 작업이다. 하지만 Virtual DOM은 메모리 상에서만 동작하며 실제 DOM을 조작을 최소화한다. React는 Virtual DOM을 사용하여 렌더링이 조금 더 빠르게 일어날 수 있도록 해준다.
하지만 Virual DOM에도 단점이 있다. DOM과 동일한 구조가 메모리에 위치하기 때문에 추가적인 메모리를 사용한다. 이는 간단한 UI나 프로젝트에서는 불필요한 오버헤드일 수도 있다.
Hook
Hook은 기존 클래스 컴포넌트에서 사용가능했던 Lifecycle API, state 관리 기능을 함수형 컴포넌트에서도 사용할 수 있도록 하는 기능이다. 흔히 보면 useEffect, useState, useContext와 같은 것들이 모두 Hook이다.
이전에 자바스크립트에서 작성한 글이 있지만 해당 글을 이해하기 위해서 간단하게 알고 넘어가야하는 개념이 있습니다.
자바스크립트는 싱글 스레드 언어입니다. 따라서 명령어 여러개를 동시에 처리하는 것이 아니라 한줄씩 처리할 수 있습니다.
2. JavaScript 구성
JavaScript 동작 출처: google Javascript엔진 검색
자바스크립트 동작을 이해하려면 자바스크립트 엔진, Web API, queue, Event Loop으로 구성되어 있습니다.
2-1. 자바스크립트 엔진
자바스크립트 엔진에는 heap과 stack이 있습니다. heap에는 원시타입, 객체타입이 선언이 되면 메모리 힙에 할당이 되고, 사용이 끝나면 자동으로 힙에서 해제됩니다. stack은 실행해야하는 코드인 실행 컨텍스트가 쌓입니다. 코드 실행시 push, 실행이 끝나면 pop이 됩니다.
여기에서 실행 컨텍스트란 실행가능한 코드가 실행되기 위해서 필요한 환경을 모아놓은 객체입니다. 기본적으로는 글로벌 컨텍스트가 스택 가장 아래 쌓이고 그 다음으로 함수 컨텍스트 들이 위로 차례로 쌓입니다.
2-2. Web API
Web API에는 Ajax 요청, SetTimeout, setInterval, 이벤트 핸들러의 등록과 같은 웹 브라우저에서 제공하는 기능들입니다. 해당 기능들은 그립과 같이 자바스크립트 엔진과는 떨어져 있는 것을 확인할 수 있습니다.
2-3. Queue
다음으로는 Queue 입니다. Queue라고 하면 선입선출, 먼저 들어온 객체가 먼저 나가는 자료구조입니다. 그림에는 Callback queue만 있는데 사실은 Callback queue를 포함해서 MicroTask queue, Animation Frame이 추가로 해서 3개의 queue가 있습니다.
우선 Callback queue는 MacroTask queue 또는 Task queue라고도 불립니다. 해당 queue는 Ajax, setTimeOut, setInterval, setImmediate와 같은 task의 결과를 넘겨 받습니다. 우선순위는 3개의 queue중에서 가장 낮습니다.
다음으로는 MicroTask queue입니다. 해당 queue는 promise, async/await, process.nextTick 과 같은 비동기 호출을 넘겨 받습니다. 3개의 queue중에서 우선순위가 가장 높습니다.
다음으로는 AnimationFrame입니다. requestAnimationFrame과 같은 브라우저 렌더링과 관련된 task를 넘겨받습니다. 3개의 queue중에서 우선순위가 2번째로 높습니다.
정리해보면 queue는 총 3개가 있으며 우선순위는 MicroTask queue > AnimationFrame > MacroTask queue 입니다.
2. console.log("start")가 Stack에 push되고 실행이 될 것입니다. 실행이 되면 Stack에서 pop됩니다.
3. 그 다음 실행인 setTimeOut()이 Stack에 쌓입니다. 이제 setTimeOut이 실행이되야하는데 위에서 setTimeout은 Web API 중 하나입니다. 따라서 순서가 이전 console.log()랑 다릅니다. 우선 Stack에서 pop이 되고난 다음 Web API setTimeout에게 실행하라고 신호를 보냅니다. 그러면 Web API에서 setTimeout을 실행시킵니다. setTimeout이 자바스크립트 엔진이 아닌 Web API에서 실행이 되면서 Stack에는 promise.resolve()가 스택에 push되는 것입니다. 이렇게 비동기 처리가 싱글스레드에서 일어나는 것입니다.
setTimeout의 실행이 끝나면 결과인 console.log("setTimeout")은 MacroTask queue에 들어가게 됩니다.
4. 이 과정이 일어나면서 Stack에서는 promise.resolve()를 실행 시킵니다. Stack에서 pop이되고 결과인 then()이 MicroTask queue에 들어가게 됩니다.
5. 마지막으로 console.log("end")가 Stack에 push되고 실행이 된 다음 Stack에서 pop됩니다.
6. 이제 더이상 실행할 코드가 없기 때문에 글로벌 컨텍스트가 pop되고 Stack은 비워집니다.
여기까지보면 console 창에는 start, end 만 적혀 있습니다
7. 이제 Event Loop가 Stack이 비워져 있는 것을 확인하고 Queue를 확인합니다. 우선 MicroTask queue에 있는 promise.resolve() 결과인 then()을 Stack에 Push시킨 뒤 코드를 실행하여 console에 promise가 추가됩니다. 그 다음 Stack에서는 pop됩니다.
8. AnimationFrame에는 아무 것도 없고 마지막으로 MacroTask queue에 있는 setTimeout() 결과를 Stack에 Push하고 실행시킨 뒤 pop합니다.
이렇게 모든 코드가 동작했습니다.
뭔가 말로 적어서 조금 난잡하긴 한데, Queue에서 링크 걸어드린 블로그를 참고하시면 많은 도움이 되실거 같습니다.
대학생때 React, ReactNative를 이용해서 팀플을 했지만 졸업하고 군대를 가고나서는 다 까먹어버림...
찾아보니 버전도 많이 바껴있고 업데이트하고 조치하는데만 2일 걸렸다는 함정;;
가고싶어하는 회사에서도 React를 사용한다고 하니 나도 공부할 겸 저 처럼 처음 시도해보시는 분들을 위한 글입니다.
React 사용 전 시스템 버전확인
Ubuntu 버전. 20.04.6 LTS를 사용하고 있다.nodejs, npm 버전
위 그림에서 처럼 글쓴이는 Ubuntu 20.04.06 LTS, NodeJs 18.15.0, npm 9.5.0을 사용하고 있다.
대학생때도 그렇고 다시 시작하는 지금도 그렇고 가장 시간을 많이 쓰는 곳 중 하나가 버전 환경을 맞추는거 같다.
처음에는 ubuntu 18.04 LTS를 사용하고 npm은 5.버전, nodeJS는 12.버전을 사용하고 있었는데 React 페이지를 보니 사용해야하는 버전이 달라진거 같았다.
출처 React 공식 홈페이지
사진에서 처럼 Node 14.0.0, npm 5.6 이상을 사용하라고 나와있다. 무시하고 진행하면 당연히 오류로 진행이 안된다..
겨우 Node 18.15.0, npm 9.5.0으로 업데이트하고나서 진행을 하려고하는데 우분투 18.04 LTS에서는 지원하지 않는다고 해서 Ubuntu 20.04 LTS로 업데이트도 하고 왔습니다.. 블럭되고 여러 실패가 있었으나 이 글을 읽으시는 분들은 미리 업데이트를 잘하시길 바래요..
React 프로젝트 폴더 만들기
이제 필요한 버전들도 설치가 되었으니 React 프로젝트 폴더를 만들어보자.
터미널에서 프로젝트 폴더를 만들고 싶은 위치로 이동한 다음 아래 명령어를 입력하면 된다.
npx create-react-app [폴더 이름]
React 프로젝트 폴더가 만들어지고 있는 과정React 프로젝트 폴더가 완성된 모습
프로젝트 폴더가 완성이되면 위 사진과 같은 화면이 나온다.
React 실행하기
프로젝트 폴더가 완성되고 난 뒤 마지막 2줄을 보면 우리가 만든 프로젝트 폴더로 이동한 다음 npm start를 입력해주면 된다고한다.
잘 모르겠지만 우선 해보자.
npm start 실행한 결과
오... 뭔지 모르겠는데 터미널에는 "Compiled successfully!" 라는 문구가 나오고 화면에 React 문양이 빙글빙글 돌고 있는 것으로 보아 실행에 성공한거 같다.
근데 우리는 어떤 코드도 입력하지 않았는데 프로젝트 폴더가 만들어지자 마자 이런 결과물이 나왔을까??
test-react/src/App.js 코드
test-react/src/App.js 코드를 보면 사진과 같이 나와있다.
아직 저 코드들이 이해가 안가도 된다. 처음하는데 이런거 어떻게 다 알아..
그런데 HTML, CSS, JavaScript 조금만 해본 사람이면 아 App.js 파일에서 작성된 요소들이 실행된거구나 라고 알 것이다.
우리는 앞으로 App.js를 수정하면서 코드를 작성하면 결과물을 확인할 수 있다.
test-react/src/index.js 코드
index.js 파일을 열어보니 위에서 본 App.js 를 import하고 render? 라는 것을 사용하고 있다.
ReactDOM은 뭐고 render은 뭐야... 많이 어렵다.
두려워하지마라. 나도 아직 기억이 가물가물해서 찾아보면서 작성하고있다. 처음부터 배워가면서 해야하고, 중도하차만 하지않으면
knex.js는 Node.js SQL builder 및 query 기능을 제공하는 라이브러리다. PostgreSQL, MSSQL, MySQL, MariaDB, SQLite3, Oracle, Amazon Redshift 등을 지원해준다. knex.js의 공식 사이트는 knexjs.org/ 이다.
2. 장점
직접 사용했을 때 장점은 기존 SQL문을 사용할 줄 안다면 거의 비슷하게 사용할 수 있다. 우리가 흔히 SQL문에서 아는 select, where, from, join 등등 다양한 query들이 포함되어 있다. 또한 지원해주는 기능도 많아서 나름 편리하다. transaction, async/await, migration 등등 을 지원해주며 사용하기 편하다. 또한 JavaScript와 SQL 코딩을 같이하는 느낌? 뭔가 데이터 베이스를 만지는거 같으면서도 일반적인 코딩하는 기분이 든다. 즉, 기존 프로그래머들이 적응하는데 오래걸리지 않는다.
3. 단점
공식 홈페이지에서 함수에 대한 설명이 조금 빈약하다. 어떤 코드를 실행했을 때 어떤 형식으로 리턴이 되는지, 어떻게 사용되는지를 조금 더 자세하게 작성해주면 좋겠다는 생각을 많이 받았다. 예를 들면 knex("table_name").select(*) 코드를 작성했을 때 "table_name"이라는 테이블에서 모든 field를 받아오는 정도는 SQL를 다뤄본 사람이라면 모두 알고 있다. 하지만 이때 return되는 값이 어떤 형태로 오는지를 설명되어있지 않았다. 실제로 나 같은경우에는 return되는 형식을 몰라서 조금 시간을 잡은 적도 있다.
*knex("table_name").select(*) 의 return은 [{row1_field1: "row1의 field1의 값"}, {row2_field2: "row2의 값"}]이다.
2020년 4학년 캡스톤 디자인에서 웹페이지를 개발할 때 PostgreSQL를 사용해서 데이터베이스를 구축했다. 이때 knex를 사용하게 되었는데 1학기에는 BackEnd를 만질 줄 아는 사람이 1명밖에 없었고 새로 배우기에는 시간이 너무 없어서 만질줄 아는 1명말고 나머지 4명은 FrontEnd기능만 맡아서 했다. 때문에, knex를 다뤄볼 일이 없었는데, 2학기에 캡스톤디자인2에서는 refactoring를 BackEnd 중심으로 진행하게 되었다. 다들 처음만질 때는 익숙하지 않다보니 막막했는데 계속 만지다보니 나름 재미도 느낀다. 하지만 BackEnd 설계 성격상 하나의 기능을 추가하거나 기존의 코드에서 바꾸려고하니 머리가 너무 아프다...
6. 결론
knex 카테고리에는 내가 knex를 다루면서 찾기 힘들었던 부분, 헤맸던 부분 등등 을 정리하기 위해서 만든 카테고리다. 그래도 해당 카테고리의 글을 작성하기전에 knex가 어떤 것인지는 설명하는 글이 있어야할거 같은 느낌이 들어서 작성해본다.
지금 캡스톤(졸업 작품)에서 아무 생각없이 JavaScript, Node.js, React, React Native를 사용하면서 갑자기 이들의 차이가 뭘까라는 생각이 들었다. '만약 면접에서 이런 질문이 들어오면 내가 뭐라고 대답할 수 있을까?' 라는 생각을 해보니 대답할 수 없을거 같더라.. 뭔가 이런 것을 생각한다는 자체가 바보같은 생각이라고 들때도 있지만 모르는게 죄는 아니잖아;; 지금부터라도 알고 써야지
그래서 이번 글에서는 이 세가지가 어떤 차이가 있는지에 대해서 정도만 알아보고자 한다. 한번 알아보는 김에 깊고 정확하게 이해하는 것도 중요하긴 하지만, 내가 이 언어쪽으로 직업을 가지거나, 주 언어로 사용을 하려는 생각이 없는데 자세하기 알기에는 안그래도 부족한 뇌 용량에 억지로 넣는 기분이다.
2. JavaScript
쉽게 말하면 JavaScript는 프로그래밍 언어 중 하나이다. 즉 우리가 흔히아는 C, C++, Python, Java와 같은 언어라고 할 수 있다. 조금 더 깊이 들어가면 객체 기반의 스크립트 프로그래밍 언어이다.(스크립트 언어를 설명하기엔 주제가 벗어나니 나중에 따로 글을 쓰게 된다면 링크를 걸어두도록 하겠다.) 따라서 JavaScript는 스크립트 언어이기 때문에 특정한 프로그램 안에서만 동작할 수 있다. 보통 Chrome, FireFox, Safari, Explore 등등에서 사용 가능하다. Chrome에서 F12를 누르면 개발자 도구를 활성화 할 수 있다. F12를 눌렀을 때 여러가지 탭이 있는데 console에서 JavaScript언어를 작성하면 동작하는 것을 확인할 수 있다.
흔히 우리는 JavaScript를 말하면 무엇이 떠오르는가? 나 같은 경우에는 JavaScript를 한번도 사용해보지 않았는데도 그냥 자연스럽게 CSS, 웹, 홈페이지 등등이 떠올랐었다. 왜 프로그래밍 언어인데 웹에 관련된 단어들이 떠올랐을가? JavaScript도 웹이랑 밀접하게 관련되어 있기 때문이다. HTML이 웹 페이지의 기본 구조를 담당하고 CSS가 웹의 디자인을 담당한다면 JavaScript는 웹 페이지가 동작하는 것을 담당한다고 할 수 있다.
JavaScript의 장점이라고 하면 확장성이 매우 뛰어난 언어이다. JavsScript만 알면 일반적인 웹 사이트 개발은 거의 할 수 있다. React.js, Vue.js, React Native 등등 다양한 라이브러리를 사용할 수 있다. 물론 그 안에서는 일반적인 JavaScript와 조금은 다른 부분들이 있지만 거의 비슷하다고 할 수 있다. 비전공자들이 이쪽 분야로 넘어왔을 때 가장 쉽게 배울 수 있는 것이 웹 관련 Front 쪽이라는 것이라고 보면 얼마나 쉽고 빠르게 배울 수 있는 언어인지 상상이 될 것이다.
3. Node.js
좋아. 그럼 JavaScript는 프로그래밍 언어 중 하나인 것은 알겠는데 JavaScript를 뜻하는 js를 확장명으로 달고 있는 Node.js는 뭐가 다른걸까?
Node.js를 이해하기 위해선 JavaScript를 먼저 배우긴 해야한다. 왜냐하면 Node.js는 JavaScript 기반으로 만들어졌기 때문이다. Node.js는 Chrome V8 JavaScript 엔진으로 빌드된 JavaScript 런타임이다. JavaScript는 Chrome, FireFox 등등 웹 브라우저에서 동작할 수 있지만 이러한 웹 브라우저가 없으면 사용할 수 없는 단점이 존재했다. 우리는 이러한 웹 브라우저 뿐만 아니라 terminal(윈도우에서는 cmd) 같은 곳에서도 사용하거나 디버깅하고 싶은데 그럴 수 없었다는 뜻이다. 하지만 Node.js는 terminal와 같은 외부 환경에서도 실행이 가능하다. 또한 Node.js를 활용해 서버를 만들 수 있다.
Node.js에는 여러 패키지들이 있는데 npm(Node.js Package Manager)로 관리가 된다. Python의 pip install로 Python 패키지를 설치하는 것처럼 비슷하다. npm install을 이용해서 Node.js에 관련된 패키지를 설치할 수 있다. Facebook에서 만든 yarn이라는 패키지 및 배포 관리자도 있는데 npm과 성능 측면에서는 큰 차이가 없다는거 같다.
4. React
React는 React.js, ReactJS라고도 불리며 JavaScript의 라이브러리 중 하나로 웹 및 앱을 개발 할 수 있다. Facebook 및 여러 공동체에 의해 유지보수가 되고 있다.
React를 사용하면 React를 지원해주는 여러 컴포넌트 관련 라이브러리를 쉽게 사용할 수 있다. 예를 들면 버튼을 구현할 때 디자인을 손보고 싶으면 Css를 통해서 수정해야했다면, Ant Design 등의 라이브러리 등을 사용하여 해당 라이브러리에서 제공하는 Button이나 여러 컴포넌트들을 사용할 수 있다.
React는 JavaScript의 라이브러리 중 하나이지만 사용해보면 State와 Props 개념의 등장으로 조금은 다른 부분이 있다는 것을 느낄 것이다. 글쓴이도 처음 React를 만질 때 State, Props 이해하느라 머리가 아팠다는.. 이 글은 React를 설명하는 글은 아니다 보니 필요하신 분들은 따로 찾아보시길 바랍니다. 그래도 이 두가지를 이해하면 쉽게 웹 페이지를 개발할 수 있고, 익숙해지면 대충 이런식으로 하면 되겠구나를 생각할 수 있는 자신을 발견할 것이다.
React는 document 사이트도 잘 되어 있고 요즘은 많이 사용하고 있어서 처음 접하더라도 쉽게 배우고 따라갈 수 있을 것이다.
5. React Native
React Native도 Facebook이 개발한 오픈 소스 모바일 애플리케이션 프레임워크이다. 안드로이드, iOS, 등의 어플리케이션을 개발하기 위해 사용되며 네이티브 플랫폼 기능과 React를 사용할 수 있게 한다.
React Native도 JavaScript 기반으로 작성하므로 나름(?) 쉽게 배울 수 있을거 같지만 초기에 꽤 많은 오류를 접한다. 특히 React Native 오류가 나면 앱에 빨간 배경에 오류 글씨가 가득차는데 정말 꼴보기 싫다... 뭔가 게임 속에서 스토리 진행하다가 죽었을 때 You DIE 문구가 나타나는 기분이랄까..?
대학교 2학년 때(2018년) 첫 팀프로젝트에서 모바일 어플리케이션을 개발할 때 처음으로 React Native를 사용해보았는데 생각보다 답답한 점이 많았다. 우선 에러가 나더라도 어느 이유에서 에러가 나왔는지 쉽게 이해할 수 없었다.. 물론 나중에 React Native에 대해서 익숙해지고 나면 '아..? 여기에서 실수했겠구나' 정도로 이해할 수 있지만 처음 개발하는 사람들에게 에러 문구를 보여주면 '음..? 이게 뭔말이여?' 라는 생각이 들게 만든다. 또한 document 사이트가 지금은 개선이 되어있는지 모르겠지만 당시에는 '이게 다야..?' 라는 말이 나왔다. stackoverflow 등에 검색해봐도 해결이 잘 안되는 경우도 많았고, 책을 사서 공부하려고해도 React Native에 관련된 책이 거의 없었다. 학교 도서관에 1권 있었는데 별 도움이 되진않았던 걸로 기억된다. 요즘은 사용하는 기업이나 시도하는 사람들이 많아서 조금은 관련 정보들이 많을 것으로 예상이 된다. 이전에 React를 만져보았다면 React Native를 다루는데 많은 도움이 될 것이다.
6. 결론
오늘은 JavaScript와 관련된 라이브러리, 플랫폼을 알아보았다. 배경에서도 말했지만 JavaScript를 주 언어로 사용할 것이 아니라면 이러한 차이들을 굳이 알아야할까? 라는 생각이 들긴한다. 하지만 안다고해서 나쁠거야 없다. 예상하지 못한 상황에서 갑자기 사용하게 될 수도 있고, 누군가가 너 이런거 알아? 라고 했을 때 아는 척이라도 할 수 있다.