Gaebal/React&Node JS

[ReactJS] 시작

ha3kkkkk 2020. 9. 22. 16:05

1. 리액트

일반적으로 웹페이지에서 화면의 값을 업데이트 할 때, 업데이트할 요소를 찾아서 업데이트 한다.

그런데 이렇게하면

규모가 크고 복잡한 어플리케이션일 수록 DOM안에서 찾는데 성능이 떨어질 수 있다. (like 페이스북)

때문에 어디를 바꿀지 찾는게 아니라 그냥 새로 만들자!(새렌더링)하는게 리액트이다.

이렇게하면 일반적으로 CPU증가.. 메모리사용증가.. DOM느림이 발생하지 않을까 싶은데

리액트는 성능을 잡아낸다.

(모든 상황에서 리액트가 빠른건 아니다. 지속적으로 데이터가 변하는 대규모 어플리케이션에 적합하다.)

 

이 리액트는 자바스크립트라이브러리(프레임워크X)로서 오로지 사용자 인터페이스를 만드는데 사용한다.

즉, View만 보는것이다. (MVC나 MVW가 아니다)

 


DOM (Document Object Model)

DOM은 브라우저에서 지원하는 개발자 툴에서 보이는 것으로,

쉽게말하면 작성한 코드(HTML, XML..)가 브라우저에 의해 파싱되면 DOM이된다.

 

Document Object(html 태그같은거)로 문서구조를 표현하는거라 보면되는데

트리 형식으로 생겼다.

https://bonedev.tistory.com/62

 

 

 

2. 렌더링

위에서 말한 렌더링이란 무엇일까.

렌더링은 사용자 화면에 View를 보여주는 것이다.

 

이 렌더링을 어떻게 해야 새롭게 리렌더링 해도 성능을 아낄 수 있는것일까?

이것을 알려면 초기렌더링리렌더링에 대한 이해가 필요하다.

 

초기렌더링은,

맨처음 어떻게 보일지 정하는 것으로 리액트의 render 함수를 이용한다.

render() { ... }

이 함수는 컴포넌트를 정의하는 역할을한다. 즉 컴포넌트를 리턴하는데..

그럼 컴포넌트는 뭘까...

 

컴포넌트는, 

리액트에서 특정부분이 어떻게 생길지 정하는 선언체이다.

 

즉 render()에서는 html 문자열 같은것을 반환하는 것이 아니라

뷰가 어떻게 생겼고, 어떻게 작동하는지 정보를 지닌 객체를 반환하는것이다.

 

일반적인 레이아웃 디자인에서 부모레이아웃 안에 여러 레이아웃을 만들 수 있는것처럼.

컴포넌트 안에도 컴포넌트가 있을 수 있다.

그래서 render()을 실행하면 내부에 있는 컴포넌트들도 재귀적으로 렌더링이된다.

render()을 통해 최상위 컴포넌트까지 렌더링이 끝나면 HTML마크업(문자열)을 만들고 DOM 요소안에 주입한다.

 

 

렌더링(render()) --> HTML 마크업(<div> ... </div>) -- 주입 --> DOM

 

 

이제 리렌더링을 알아보자

 

먼저 간단한 용어설명을 더하자면(용어설명이 끝이없다..)

뷰의 값을 업데이트 하는것은 업데이트 과정이라 부르지 않고 조화 과정이라 부른다.

 

뷰의 값을 업데이트할 때 새로운 값을 가지고 render()함수가 또 호출되고,

그러면 업데이트 값이 반영된 컴포넌트(뷰)가 생성될것이다.

 

이때 DOM에 이것을 바로 반영하지 않고

현재의 컴포넌트와 만들어진 컴포넌트를 비교한다. (JS를 이용하여 최소한으로 비교한다고한다..알고리즘의힘..)

비교하여 알아낸 둘의 차이를 최소한의 연산으로 DOM에 반영한다.

 

이때 우리는 현재의컴포넌트를 DOM이라 부르고

만들어진 컴포넌트를 Virtual DOM이라 부른다.

이 Virtual DOM은 리액트에서 사용되는 것으로 DOM의 사본이라 생각하면 쉬울 것같다.

 

 

일반적으로 DOM에 변화가 일어나면,

웹브라우저가 CSS를 다시 연산하고, 레이아웃을 굿어하고, 페이지를 리페인팅하는 작업이 발생하는데

Virtual DOM을 이용하면 DOM 업데이트를 추상화함으로써, DOM 처리횟수를 최소화할 수있다.

 

이론이 지루하니 환경세팅을 시작해보자.

 

 

2. 개발 환경

 

개발 환경 셋팅은 간단하다.

나는 리눅스를 이용하여 셋팅하였는데, 윈도우인 사람은 에디터를 먼저 설치하면 된다.(Subline Text, VSCode 등)

 

nodejs와 npm을 설치하고 나서 아래의 명령어를 입력해서 프로젝트를 만들자

(일반적으로 yarn을 많이 쓰는데.. 개인적으로 안쓰던 무언가를 쓰는건 회피하게 되어서 npm을 쓴다. 나중에 npm 쓰다가 제대로 안되는 부분이 있으면 yarn으로 넘어갈 수도 있을 것같다. 제발 안그랬으면 좋겠다. 이사태를 방지하고 싶은 사람은 yarn을 쓰는걸 추천한다.)

 

$ npm init react-app hello

 

만들어진 프로젝트를 실행해보자

$ cd hello

$ npm start

 

이제 localhost:3000을 입력하면 리액트 페이지를 볼 수 있다. (기본 포트가 3000이다.)

 

3. 코드 이해

init(create) react-app 명령어를 실행하면 node_module 이라는 디렉터리가 생성된다.

이 디렉터리안에 react 모듈이 설치되어있고, 

vi src/App.js를 하면 가장 첫 줄에 react 모듈을 불러오는 것을 확인할 수 있다. (import React from 'react')

 

브라우저가 아닌 환경에서 자바스크립트 실행을 해주는 node.js 를 사용하기 때문에 이렇게 모듈을 불러올 수 있다.

 

이 기능을 제공하는게 번들러(Bundler)인데

번들러는 import로 부른 모듈을 하나로 합쳐 하나의 파일로 생성해준다. (모듈이든, svg든, css든 로드해준다)

보통 번들러로 웹팩을 사용한다.

 

App.js의 코드는 아래와 같은데, 

function App() { ... } 이부분이 App이라는 컴포넌트를 만드는 부분이다. (function 키워드로 컴포넌트를 만들 수 있다.)

 

import React from 'react';
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;

 

src/index.js 코드를 보면 App.js의 App을 무슨 html 태그 사용하듯 간편하게 부르는 것을 확인할 수 있다.

 

import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import * as serviceWorker from './serviceWorker';

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

// If you want your app to work offline and load faster, you can change
// unregister() to register() below. Note this comes with some pitfalls.
// Learn more about service workers: https://bit.ly/CRA-PWA
serviceWorker.unregister();

 

요건

리액트의 문법인 JSX를 이용한 것인데 다음 글에서 확인하자.