[React] DOM 객체와 SPA로 이해하는 리액트의 폴더 구조
안녕하세요.
이번 시간에는 리액트의 폴더구조에 대해 알아봅시다.
최근 리액트를 공부할 일이 생겨하다 보니 이해가 되어서
이해한 내용을 정리해서 올릴 예정입니다:)
우선 리액트의 폴더 구조를 이해하기 위해서는 HTML DOM 객체와 SPA에 대한 이해가 필요합니다.
HTML DOM (Document Object Model)이란?
HTML이란 공식 문서로는 W3C의 표준으로 XML, HTML 문서의 각 항목을 계층으로 표현하여 생성, 변형, 삭제할 수 있도록 돕는 인터페이스라고 한다. 그러나 간단하게 이해하는 HTML DOM은 태그를 제어하는 인터페이스라고 보면 편하다.
즉 HTML 태그가 출력된 모양이나 콘텐츠를 제어하기 위해 HTML 태그 당 하나의 DOM 객체가 생성되고 이는 DOM 노드 또는 DOM Element라고 불린다.
예를 들어 로그인 회원가입이 연달아 있을 때 DOM 객체를 이용하여 세션이 있으면 로그아웃 회원가입 버튼을 보여주고 세션이 없으면 로그인 회원가입 버튼을 보여주도록 태그를 제어할 수 있다.
이러한 DOM 객체의 중요내용은 두 가지다. 우선 DOM 객체는 최상위 documnet 객체를 기준으로 계층구조로 이루어져 있다. 이를 DOM 트리라고 한다. 이는 HTML 태그의 포함관계에 따라 트리가 구성되며 부모 자식 관계를 갖는다.
간단하게 이해하면 아래 예시와 같이 목록을 만드는 <ul> 태그와 <li> 태그는 <ul> 태그가 <li> 태그를 아래와 같이 감싸는 형태로 구성된다. 이는 DOM 객체로 이해하면 <ul> 태그가 상위 태그고 <ll> 태그가 이의 자식 태그가 되는 것이다
/* 상위 하위 예시 */
<ul>
<li> 사과 </li>
<li> 토마토 </li>
<li> 바나나 </li>
<ul>
이렇게만 들으면 감이 안 오니 DOM 객체의 주요 함수를 살펴보자. 중요한 건 이 함수들은 태그 내에서 사용하는 게 아니라 <script> 태그 내에서 사용하는 것이다. 이외에도 DOM트리에 삽입/삭제하는 함수 등 더 많지만 주요 내용만 정리했다.
이 중에서 getElementById와 createElement를 유의 깊게 봐둘 필요가 있다.
함수명 | 기능 |
document.getElementById('태그의 id명') | 태그의 id 값으로 해당 태그를 찾는 것 |
document.getElementsByClassName('class 변수명') | 태그의 class 값으로 해당 태그를 찾는 것 |
documnet.getElementsByTagName('태그명') | 태그명(종류)으로 객체를 찾는 것 |
document.write('출력할 내용') | HTML 콘텐츠 마지막에 내용을 출력해 준다. |
documnet.writeln('출력할 내용') | HTML 콘텐츠 마지막에 내용을 출력하고 줄바꿈 해준다. |
document.createElement('태그이름') | 태그명에 해당하는 객체를 생성해줌 |
SPA와 MPA란?
SPA와 MPA란 각각 Single Page Application과 Multi Page Application의 약자로 기존 HTML, CSS, Javascript로만 구성된 원시 웹페이지가 MPA에 해당하고 리액트가 이제 필요한 부분만 랜더링 해서 사용하는 SPA에 해당한다.
이는 말 그대로 SPA는 웹페이지의 모든 내용이 한 파일(한 html 파일)로 구성되어 있는 것이고 MPA는 페이지마다 각각의 html 파일이 존재해서 여러 파일로(여러 html 파일)로 구성된 것을 의미한다.
그래서 이것이 왜 중요하냐면 리액트 전체의 동작구조를 아우르고 있기 때문이다. 기존 HTML만 사용하는 웹페이지의 경우 한 페이지마다 한 파일이 생기게 된다. 이렇게 되면 페이지가 많은 웹사이트는 용량이 너무 커지게 돼서 효율이 떨어진다. 따라서 부분적으로 내용이 업데이트되거나 혹은 용량이 큰 웹사이트의 경우 리액트처럼 최상위 파일 하나만 존재하고 나머지는 필요한 부분만 랜더링 하는 같은 SPA 방식의 개발이 효율적이다.
이제 본론으로 돌아와서 리액트의 폴더 구조에 대해 살펴보자.
리액트의 주요 폴더 구조
리액트의 폴더 구조는 아래와 같습니다. 크게 node_module과 public, src 폴더가 있고 그 하위에는 각각 아래와 같은 파일이 들어 있습니다. 더 세부적인 파일도 많지만 이번장에서는 주요한 핵심적인 파일과 구조를 위주로 리액트를 이해해보겠습니다.
폴더명/파일명 | 역할 |
node_modules | node 관련 환경설정 및 개발 환경 구축 관련 |
public/index.html | 랜더링할 컴포넌트들의 부모 태그를 선언하는 곳 |
src/App.js | 컴포넌트를 선언하는 곳 |
src/index.js | 최상위 컴포넌트 App을 정의하고 DOM 객체를 랜더링하는 곳 |
우선 node module은 npm start로 서버를 구동할 때 필요한 여러 파일들이 들어 있는 폴더입니다
# index.html
다음으로 index.html이 리액트에 존재하는 유일한 html 파일로 최상위 태그가 선언된 곳입니다. 아래와 같이 public 폴더에 존재하는 index.html은 기존 원형의 html 파일의 형식(<head/><body/>)을 갖추고 있습니다. 이 파일에서 주목할 부분은 우측에 빨간 박스를 친 <div id='root'></div>입니다.
<div> 태그는 안에 내용도 없이 왜 있는 것일까요? 정답은 id='root'를 설정하기 위해 존재합니다.
?????
이렇게 선언된 <div> 태그는 index.js 파일에서 getElementById('root')로 이 태그의 위치(**)에 내용이 랜더링 됩니다.됩니다
그리고 그 자리, 즉 아래 div 태그가 있는 자리에 앞으로 생성할 콘텐츠들이root.render()를 통해 나타 되게 됩니다.
간단하게 말해서 콘텐츠를 생성할 루트 위치를 id 속성으로 정의하는 파일입니다. (<div id='root'></div>)
# index.js
다음으로 src 폴더에 위치한 index.js는 무엇을 하는 곳일까요? index.js는 아래와 구성됩니다.
index.js는 최상위 컴포넌트로 빨간 박스와 같이 getElementById로 index.html에서 name 속성이 root인 태그 자리에
<App/> 컴포넌트를 랜더링 하는 역할을 합니다! (너무너무 중요한 말입니다.)
# App.js
이제 위에서 index.js와 index.html을 통해서 <App/> 컴포넌트를 랜더링 하였었습니다.
그러면 App.js에서는 어떤 역할을 할까요? App.js는 생성한 여러 컴포넌트들의 리스트를 선언하거나 컴포넌트를 라우팅 하는 곳입니다. 라우팅이란 리액트에서 페이지를 연결하는 방식입니다. 이 말이면 모든 정리가 끝납니다.
App.js 파일은 컴포넌트 리스트를 선언하거나 이들을 라우터로 연결하는 곳입니다.
그래서 결론적으로 기억해야 할 부분은 아래와 같습니다. 리액트의 폴더 구조는 상/하위 관계를 가지고 있습니다. 그중에서 가장 최상위에 있는 컴포넌트는 index.js이고 이 index.js가 index.html에 App.js를 랜더링 하는 역할을 합니다. 그리고 App.js에는 여러 컴포넌트들이 선언되고 연결되어 있습니다.
이러한 리액트의 구조를 한 그림으로 정리하면 아래와 같습니다.
따라서 이후 컴포넌트가 생성된다면 이 <App/> 아래에 하위 컴포넌트로 존재하게 됩니다. 컴포넌트의 설계와 구조에 대해서는 따로 포스팅을 올릴 것이므로 이 장에서는 넘어가겠습니다.
그럼 이상으로 리액트의 폴더구조와 주요 파일에 대해 정리해 보았습니다.
오늘도 읽어주셔서 감사합니다.