React 재활훈련- 2일차, React 소개

0

react

목록 보기
2/11

https://www.udemy.com/course/react-next-master/

Introduction to React

react는 opensource javascript library로, 컴퓨터넌트 기반의 UI 표현이 가능하다. 즉, UI를 모듈화하여 마치 블럭을 붙이듯이 개발을 할 수 있다.

또한, react를 통해서 UI상에서의 interaction을 매우 편리하게 update할 수 있다. 이는 virtual DOM 덕분으로 개발자가 성능에 크게 상관하지 않아도 web browser의 UI를 매우 빠르게 update할 수 있는 것이다.

Virtual DOM

react는 virtual dom을 사용하기 때문에 개발자가 충분히 빠르게 interaction에 따른 UI update를 할 수 있다.

먼저, 웹 브라우저의 렌더링 과정이 필요하다(critical rendering path)

HTML --> DOM(document object model)
          |
        Render Tree --> Layout --> Painting
          |
CSS  --> CSSOM(css object model)

html, css 파일을 object로 표현한 것이 DOM, CSSOM이고 이들을 합쳐서 하나의 tree로 만드는 것이 render tree이다.

render tree는 html로 표현한 요소들의 계위, 모양과 css로 표현한 요소들의 스타일을 합친 하나의 웹 페이지 청사진이다.

render tree를 만들었다면 이제 Layout을 만든다. 이는 화면에 나타날 요소들의 위치와 크기라고 생각하면 된다.

마지막으로 Painting단계를 거쳐 요소들을 실제로 화면에 그린다.

문제는 화면에 interaction이 발생하면 이 과정을 다시 거쳐 웹페이지를 재성성해야한다는 것이다.

HTML --------> DOM(fix)
  수정->|       |
Javascript   Render Tree --> Layout --> Painting
                |
CSS  --------> CSSOM(css object model)

javascript를 통해서 DOM에 직접 접근하여, document의 배치, 모양, 값들을 변경, 추가, 삭제 등이 가능하다. 이렇게 DOM이 변경되면 render tree를 다시만들고 layout을 다시 잡고 painting을 다시 실행한다.

여기서 rendering되는 과정에서 layout, painting과정이 굉장히 오래 걸린다.

  1. Reflow: layout을 다시 만드는 과정
  2. Repaint: 다시 paint를 만드는 과정

잦은 reflow, repaint는 성능 저하의 주요 주범이다. 그래서 javascript로 1000번 update할 것을 1번 update하도록 변경하는 것이 좋다. 그런데 이렇게 update를 한번에 모아서 실행하는 것은 서비스가 복잡해짐에 따라 굉장히 어려워진다.

그래서 virtual DOM이 이 문제를 해결해주는 것이다.

(+React)
JavaScript ---> Virtual DOM ---> DOM(fix)

virtual DOM에서 동시에 발생한 update를 모아서 DOM을 한번만 수정시킬 수 있도록 도와주는 것이다. 즉, 하나의 buffer역활을 하는 것이다.

virtual DOM은 javascript로 이루어진 가상의 DOM으로 actual DOM의 사본이다. 먼저 update가 발생하면 virtual DOM에 update를 반영하고, 또 다른 interaction들이 발생하여 update가 생기면 virtual DOM에 또 update를 반영한다.

이렇게 virtual DOM에 update들을 반영하여 update들이 쌓이고 update가 발생하지 않으면 actual DOM에 virtual DOM을 반영시키는 것이다. 그래서, n번 DOM을 update해야할 것을 virtual DOM을 통해서 n번보다 적게 DOM을 update할 수 있는 것이다.

이를 통해서 개발자는 reflow와 repaint과정을 줄일 수 있어, 성능상에 굉장히 큰 이점을 볼 수 있다.

가령 다음과 같이 virtual DOM과 Actual DOM이 있다면

Virtual DOM                     Actual DOM

            |DOM|                     |DOM|
              |                         |
        -------------               -------------
        |           |               |           |
      |DOM|       |DOM|            |DOM|      |DOM|

update발생할 시에 다음과 같이 된다.

Virtual DOM                     Actual DOM

            |DOM|                     |DOM|
              |                         |
        -------------               -------------
        |           |               |           |
      |DOM|      |DOM-1|           |DOM|      |DOM|

즉, virtual DOM만 변경이 반영되는 것이다. 또 update가 발생하면 다음과 같이 된다.

Virtual DOM                     Actual DOM

            |DOM|                     |DOM|
              |                         |
        -------------               -------------
        |           |               |           |
      |DOM-1|      |DOM-1|         |DOM|      |DOM|

이제 update가 끝났다면 actual DOM에 virtual DOM의 내용을 반영한다.

Virtual DOM                     Actual DOM

            |DOM|                     |DOM|
              |                         |
        -------------               -------------
        |           |               |           |
      |DOM-1|      |DOM-1|       |DOM-1|      |DOM-1|

이렇게 virtual DOM을 통해서 actual DOM의 reflow, repaint 과정을 줄여 성능의 최적화를 이루게 만드는 것이 바로 react의 핵심인 것이다.

React Application

react library를 통해서 설치가 가능하지만, 굉장히 귀찮고 복잡하다. 왜냐하면 react를 쓰기 위해서는 react만 설치해서는 안된다. 다른 library들을 사용하여 설치해야하는데, 이 과정이 매우 복잡하다.

그래서 vite3를 사용하여 react를 편리하게 설치해보도록 하자. npm을 통해서 설치가 가능하다.

npm create vite@latest

참고로 vite@latest는 react의 최신 버전으로 설치하겠다는 것이다. project이름과 framework, variant등을 물어볼텐데 다음과 같이 입력하면 된다.

✔ Project name: … selection2
✔ Select a framework: › React
✔ Select a variant: › JavaScript

이후 설치가되고 selection2라는 directory가 만들어진다. 이 directory안에 react project에 대한 기본적인 설정들이 다 있다.

  • package.json
{
  "name": "selection2",
  "private": true,
  "version": "0.0.0",
  "type": "module",
  "scripts": {
    "dev": "vite",
    "build": "vite build",
    "lint": "eslint . --ext js,jsx --report-unused-disable-directives --max-warnings 0",
    "preview": "vite preview"
  },
  "dependencies": {
    "react": "^18.2.0",
    "react-dom": "^18.2.0"
  },
  "devDependencies": {
    "@types/react": "^18.2.66",
    "@types/react-dom": "^18.2.22",
    "@vitejs/plugin-react": "^4.2.1",
    "eslint": "^8.57.0",
    "eslint-plugin-react": "^7.34.1",
    "eslint-plugin-react-hooks": "^4.6.0",
    "eslint-plugin-react-refresh": "^0.4.6",
    "vite": "^5.2.0"
  }
}

그런데, dependency가 있지만 node_modulespakcage-lock.json이 없다. 따라서 npm install로 설치시켜주도록 하자.

npm install

참고로 devDependencies는 빌드 후에 필요하지 않은 패키지들로 오직 개발 과정에서만 쓰는 package들을 말한다.

pakcage 구조를 보면 다음과 같다.

- public: 정적 파일, 이미지 등을 넣는다.
- src: source code가 담긴 directory
    - assets: code에서 동작시키는 정적 파일, 이미지 등을 넣는다.
    - x.jsx: javascript의 확장자로 react에서 사용되는 문법이다.
- index,js
- vite.config.js: vite에 필요한 설정들을 넣는다.                                                                

이제 실행시켜보도록 하자.

npm run dev

다음과 같은 화면이 나온다.

  VITE v5.2.11  ready in 164 ms

  ➜  Local:   http://localhost:5173/
  ➜  Network: use --host to expose
  ➜  press h + enter to show help

http://localhost:5173/브라우저에 접근하면 webpage가 나올 것이다. 해당 terminal에서 h + enter를 누르면 단축시키가 나오는데 q가 종료 명령어다.

  Shortcuts
  press r + enter to restart the server
  press u + enter to show server url
  press o + enter to open in browser
  press c + enter to clear console
  press q + enter to quit

React operation logic

npm run dev로 실행시키면 http://localhost:5173에 도입시키면 우리의 react application이 나오게 된다. 이 말은 우리 컴퓨터에 react application server를 가동시켰다는 것이다.

따라서, 다음과 같이 정리할 수 있다.

                |---------my computer------------|
Cliet --요청--->|                                |
                | Web Browser --요청-- react app |
                |  (Chrome)             (5173)   |
                |--------------------------------|

결국 web browser가 우리의 computer에 떠있는 react application server에 요청을 보내어 react application을 받아 렌더링하는 것이다.

web server는 index.html을 web browser로 보내주어 rendering이 이루어진다.

그런데, 우리의 index.html 파일을 보면 조금 이상하다.

<!doctype html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <link rel="icon" type="image/svg+xml" href="/vite.svg" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Vite + React</title>
  </head>
  <body>
    <div id="root"></div>
    <script type="module" src="/src/main.jsx"></script>
  </body>
</html>

여기서는 <div id="root"></div>만 있지 내용이 없다.

사실 <script type="module" src="/src/main.jsx"></script>의 javascript가 동적으로 react 컴포넌트를 생성하여 web browser에 보여주고 있기 때문에, index.html 파일 자체에는 컴포넌트가 없다.

그래서 main.jsx에 들어가보도록 하자.

  • main.jsx
import React from 'react'
import ReactDOM from 'react-dom/client'
import App from './App.jsx'
import './index.css'

ReactDOM.createRoot(document.getElementById('root')).render(
  <React.StrictMode>
    <App />
  </React.StrictMode>,
)

잘보면 root id요소의 DOM을 가져와서 ReactDOM이 render를 실행한다는 것이다. 이때 render아래에 있는 <App/>이 바로 react의 component이다. 따라서, root div아래에 react component들이 생성되는 것이다.

  • app.jsx
import { useState } from 'react'
import reactLogo from './assets/react.svg'
import viteLogo from '/vite.svg'
import './App.css'

function App() {
  const [count, setCount] = useState(0)

  return (
    <>
      <div>
        <a href="https://vitejs.dev" target="_blank">
          <img src={viteLogo} className="logo" alt="Vite logo" />
        </a>
        <a href="https://react.dev" target="_blank">
          <img src={reactLogo} className="logo react" alt="React logo" />
        </a>
      </div>
      <h1>Vite + React</h1>
      <div className="card">
        <button onClick={() => setCount((count) => count + 1)}>
          count is {count}
        </button>
        <p>
          Edit <code>src/App.jsx</code> and save to test HMR
        </p>
      </div>
      <p className="read-the-docs">
        Click on the Vite and React logos to learn more
      </p>
    </>
  )
}

export default App

return 아래의 tag들이 실제로 렌더링되는 web browser에 반영되는 것이다.

0개의 댓글