리액트는 페이스북, 인스타그램, 넷플릭스 등을 비롯한 유명 서비스들에 사용된 기술로 많이 사용되고 있는 프론트엔드 기술입니다. 2013년 페이스북 팀이 개발한 오픈소스로, 서비스의 변화가 쉽고 사용자와 상호작용이 원활하도록 할 수 있는 기술 개발을 목적으로 만들어졌습니다.
그럼 이러한 React 사용을 위해 로컬 환경(Visual studio 이용)에서 리액트 프로젝트를 시작하는 방법을 설명하고, 그 작동 원리를 이해해보겠습니다.
리액트앱 생성하기 Create React App
프로젝트를 생성할 폴더를 Visual Studio 로 열고, 터미널을 열어 아래 코드를 입력합니다.
여기서 만일 Need to install the following packages: ... 라는 메세지가 뜰 경우 y를 입력하면 됩니다.
npx create-react-app .
※ npx = Node Package Execute (노드 패키지 실행)
※ . 은 현재의 폴더를 의미합니다.
설치에는 최대 5분정도 소요되니 이점 참고해서 진행해주세요. 설치가 완료되면 터미널에 Success! Created ... 이런 식의 문구가 뜹니다.
의존성 충돌 오류가 났을 경우
저같은 경우는 초기에 설치를 하다, 아래와 같은 오류가 떴는데,
npm error code ERESOLVE
npm error ERESOLVE unable to resolve dependency tree
찾아보니 의존성 충돌에 의한 오류였습니다. 프로젝트는 리액트의 최신버전 19.0.0을 사용하려하는데, @testing-library/react가 React 18.0.0 버전을 peer dependency로 요구해서 그런 거라고 하더라고요. 그래서 package.json 파일에서 react 버전을 18 버전으로 낮춰 설정하여 해결했습니다.
비슷한 오류가 뜨신다면 참고해보셔도 될 것 같습니다.
{
"dependencies": {
"cra-template": "1.2.0",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-scripts": "5.0.1",
"web-vitals": "^2.1.4"
}
}
생성한 리액트앱 실행하기
리액트앱 생성을 완료했다면 아래 코드를 터미널에 입력해 앱을 실행합니다.
npm run start
터미널에 위와 같은 문구가 뜨며 실행이 정상적으로 수행되면, http://localhost:3000/ 주소로 창의 띄워지며 아래와 같은 기본 리액트 화면이 보여집니다.
리액트 초기 화면에는 Edit src/App.js and save to reload 라는 문구가 뜨는데, src 폴더의 App.js를 수정하고 저장해서 다시 로드하라는 의미입니다.
App.js 파일을 열어보면 아래와 같이 구성되어있고, App 내부의 요소들을 수정해서 다시 로드하면 반영되는 것을 확인할 수 있습니다.
import logo from './logo.svg';
import './App.css';
function App() {
return (
<div className="App">
<header className="App-header">
<img src={logo} className="App-logo" alt="logo" />
<p>
Edit <code>src/App.js</code> and save to reload.
</p>
<a
className="App-link"
href="https://reactjs.org"
target="_blank"
rel="noopener noreferrer"
>
Learn React
</a>
</header>
</div>
);
}
export default App;
리액트의 페이지 렌더링 원리
먼저 사용자가 주소 입력을 통해 요청하면, 리액트 앱 서버는 웹 페이지 파일인 public폴더의 index.html을 보내게 됩니다. 그런데 이 index.html 파일 의 body 내부를 보면 딱히 보여질만한 게 없습니다.
...
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div>
<!--
This HTML file is a template.
If you open it directly in the browser, you will see an empty page.
You can add webfonts, meta tags, or analytics to this file.
The build step will place the bundled scripts into the <body> tag.
To begin the development, run `npm start` or `yarn start`.
To create a production bundle, use `npm run build` or `yarn build`.
-->
</body>
...
개발자 도구를 살펴보면 단서를 찾을 수 있습니다. bundle.js 는 src 폴더 내부의 index.js와 이 파일이 불러오는 모든 모듈을 하나로 묶어놓은 파일입니다.
bundle.js 더 알아보기
bundle.js는 웹팩(Webpack)이라는 모듈 번들러에 의해 생성되는 파일로, React 프로젝트의 모든 JavaScript 파일들(컴포넌트, 유틸리티 함수 등)과 import된 모듈들을 하나의 파일로 묶어줍니다.
묶어주는 목적은 아래와 같습니다.
1) 하나의 파일만 요청하게 함으로써 네트워크 요청 시, 성능 향상
2) 번들링 과정에서 코드가 압축하고, 불필요한 코드를 제거해 코드 최적화
3) 최신 Javascript 문법을 브라우저가 이해할 수 있는 코드를 변환함으로써 브라우저와의 호환성 향상
index.js 파일을 살펴보면, 아래와 같이 되어있고
import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<React.StrictMode>
<App />
</React.StrictMode>
);
// If you want to start measuring performance in your app, pass a function
// to log results (for example: reportWebVitals(console.log))
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
reportWebVitals();
리액트의 App 컴포넌트를 import 해서 사용하고 있으며, ReactDOM.createRoot라는 인수로 전달한 요소를 리액트 앱의 루트 컴포넌트로 만들어 반환하는 메서드가 사용되고 있습니다.
이후, root.render가 되면 내부적으로 전달된 리액트 컴포넌트가 돔에 추가되어 렌더링 되어 웹 페이지에 보여지게 되는 원리입니다.
즉 정리하면,
1) index.html이 클라이언트 요청에 의해 반환되면 index.html은 bundle.js를 실행시켜 index.js에서 작성된 코드가 실행되게 됩니다.
2) index.js 에서는 ReactDOM.createRoot 메서드를 통해 루트 컴포넌트가 지정되게 되고,
3) render를 통해 루트 컴포넌트를 비롯한 자식 컴포넌트까지 모두 렌더링되며 웹페이지에 보여지게 되는 것 입니다.
※ 주요 용어 정리
Dom(Document Object Model) : 문서 객체 모델
렌더링 (Rendering) : 브라우저가 웹의 3가지 언어 HTML, CSS, Javascript를 해석해 페이지의 요소들을 실제로 그려내는 과정.