React JS 입문 - 10만에 보는 리액트
요즈음 가장 핫한 개발언어가 무엇이 있나요?
...라고 하면 그 중하나로 React 라고 할 수 있을 정도는 되는 것 같습니다.
2000년대 Javascript에서 JQuery가 나올 때, 세상에 가져온 충격과 비슷하다고 합니다. (??!!)
사실, 저는 이 당시 Front-End에 별 관심이 없어서,, JQuery는 Javascript의 축약버전 정도로 생각하고 크게 염두에 두지 않았었습니다..
좀더 솔직히 말하면 그 이전 Javascript는 너무 지저분해서 좋아하지 않았었습니다.
그런데 지나고 나서 보니, JQuery가 내가 Web Front End에서 싫어하는 많은 부분을 제거 했던것 이며,
이를 시작으로 다양한 분야로 확장되는 Big-Bang이 일어났던것을 깨달았죠~
사실, 지금 생각해서 Jquery 자체는 별거 아닌데, 문화가 그렇게 중요한 것 같습니다.
현 Web Front end에서 React 가 차지하는 역할이, 그 당시 JQuery와 비슷하다고 합니다.
아직, 공부하는 중이라서 이게 그렇게 많이 와 닿지는 않고 있다.
일단은, Front End에서 다시 다양성과 창의성이 발휘되는 문화를 만들만큼 Hot하게 되었다는데 주목해 볼 필요가 있겠습니다.
# Virtual DOM
React를 거론하면 항상 동반되는 이야기가 Virtual DOM 입니다.
매번 들어도 내용을 알겠는데 그게 뭐 어떠냐는 거다.. 가슴이 울리지 않았는데요.
그러나, 이번에 조금 느껴지는 게 있었는데, 그 내용을 아래 적어보았습니다.
- Front End는 상당히 코드가 지저분 해 지고, 그 Component들의 갯수가 매우 많다.
- 이 때문에, 구조 또한 지저분해져서 나중에는 도저히 손을 델수 조차 없게 되어버린다.
- 그래서 Front End 는 영역 차원에서 간결성, UI와 Biz. Logic의 분리 등이 매우 중요해 지게 됨
- 이러한 이유로 등장한 것들이 MVC (model View Control) 등의 구조임
- 어떻게 하면 더 간결하게 할까 해서, JQuery가 나온것도 이런 측면이라 할 수 있음
- JQuery를 기반으로 또 다시 파생되는 Library 들 또한 이와 목적은 유사함
좀 다른 측면에서,
매우 복잡해 질수 있는 Front End에서, 동적 변수 (Dynamic Value)와 상태값들을 반영하려면 어떻게 할 것인가?
- 예를 들어, 만약 counter를 하나 만든다고 하면,
- Button을 누를 때 마다 value 가 올라가도록 해야 하며, 이 때 상태가 변하게 되고 이를 관리해 주어야 함
- 그런데, 만약 뒤죽박죽 섞여 있는 Front End 상황 (유연성이 높다보니)이라면, 여기저기 꼬일 상황이 많음
- 이러한 이유로, "지속적인 상태관리 --> 출력 ==> 결과 상태관리 반영 ==> 다시 출력 ==> ...." 이라는 컨셉을 버림
- 대신, 매번 새롭게 출력하자... 라는 컨셉으로 전환
- 이러한 방식의 단점은, 매번 모든 요소들을 "재출력"하면 리소스 낭비가 심해지고, 느려지고,, 다양한 문제가 발생함.
- 따라서, 메모리 안에서 재출력을 하고, 실제 physically 출력은 변경분만 출력하자...라는 생각을 하게 됨.
- 여기에서 "메모리 안"이라고 표현한 부분이 Virtual DOM 이라고 보면됨
그렇다면 Node JS 는 어떻게 봐야 하는가?
위에서 설명하던 컨셉의 이어 간다면,
- 기존 Javascript 가 Client / Front End Side에서만 동작하던 것이라면,
- 기왕에 만든거 서버 사이드에서도 동작하게 만들자...라는 컨셉임
- 클라이언트에서 구동하던 엔진을 서버형으로 만들어서 서버에 탑재하도록 엔지만 별도로 빼서 구동 할 수 있도록 해줌 (V8엔진 등)
- 즉, 일종의 Javascript 구동기라고 볼 수 있음... Middleware ??? ^^
이 또한 일종의 혁신 이었다.
이로서 Front End 개발자들이 대거 Back End로 유입 되었을 뿐만 아니라,
클라이언트와 서버간의 유사한 코드가 공유 됨으로 써, 수많은 라이브러리가 재 생산되는 생태계를 제공하게 되었다.
# ES6 는 무엇인가?
Javascript 버전 차이에 따른 다양한 버전이 있다.
이로 인하여 Javascript 버전 변환을 위하여 등장한 것이 Babel이다.
# WebPack
Node JS, JQuery 등의 생태계 발전으로 인하여 Javascript 단순한 Script 역할을 넘어서서 Production을 위한 Client/Server,
Front-End 개발이 가능하게 되었으며, 파생된 다양한 Library들이 존재하게 되었다.
Library들의 존재로 인하여, Import / Export 및 리소스 관리 등 프로젝트급의 개발환경으로 발전하였다.
C++, Java, C# 등 기존 프로그래밍 언어에서는 Project 관리 파일이 있으며, Linux 환경에서는 Makefile이 있고,
Java는 빌드 관리를 위한 gradle / Maven 등이 있다.
그런데, Javascript는 어떻게 Library 및 프로젝트 관리를 하는가???
-
다양한 파일/라이브러리 관리
-
라이브러리가 사용하는 스코프 관리
-
리소스 관리
-
의존성
Javascript에서는 Bundle이라는 표현으로 이를 처리하며, 이 역할을 위해서 WebPack을 사용한다.
위 이미지는 모듈이 많아 질 수록 모듈간의 의존성이 높아지는 것을 설명하고 있다.
위 그래프의 관계상, 의존성의 시작점을 Entry라고 한다.
WebPack은 Entry를 통해서 의존성있는 모듈을 로딩하고, 하나의 파일로 묶는다.
하나의 파일로 묶은 결과물을 Output이라고 한다. ==> Bundle
webpack.config.js
module.exports = {
output: {
filename: 'bundle.js',
path: './dist'
}
}
위 config는 /dist 디렉토리에 bundle.js 파일로 결과를 저장하기 위한 설정이다.
이렇게 bundle.js 로 번들링 된 Output 파일은 html에 로딩될 수 있다.
<body>
<script src="./dist/bundle.js"></script>
</body>
webpack의 실행은 Command Line에서 “webpack”명령어로 실행한다.
webpack
# loader
그런데, WebPack은 모든 것을 JS로 밖에 인식하지 못한다.
이것을 달리 말하면, WebPack에 의하여 bundle.js로 번들링 되는 것은 모두 js 문법으로 변경되어야 한다는 이야기이다. ^^;;;
이것은 css, image (png, jpg 등) 모든 파일을 포함한다.
이러한 이유로 각 형태을 다른 파일들을 js 형태로 불러 들일 수 있는 loader,
js로 변환된 내용을 web page에 적용할 수 있는 적용기 들을 필요로 하였다.
(각 변환/적용 모듈들은 npm으로 설치 필요)
loader는 test, use로 구성되며, 제외 대상을 위해 exclude가 포함되기도 한다.
다음은 CSS파일을 번들링 하기 위한 설정이다.
webpack.config.js:
module.exports = {
module: {
rules: [{
test: /\.css$/,
use: ['style-loader', 'css-loader']
}]
}
};
> test 키값으로, 확장자를 css로 같는 모든 파일을 번들링 대상으로 선택하였다.
> 번들링 할 때, Loader로 css-loader와 style-loader의 사용이 필요한다. (변환 모듈들)
* css-loader는 .css 파일을 읽어서 js문법으로 변환한다.
* style-loader는 js문법으로 표현된 css를 Element에 적용한다.
대상 리소스인 style.css 파일의 내용은 아래와 같을 때,
src/style.css:
body {
background-color: green;
}
css-loader에 의하여 변환된 bundle.js의 결과이다.
dist/bundle.js:
// module
exports.push([module.i, "body {\n background-color: green;\n}\n", ""]);
# JSX
에효....많이도 등장한다..
그런 또 JSX는 무엇인가?
JSX는 XML의 형태를 차용한 표현법 중 하나 이다.
HTML과의 차이점은 아래와 같다.
-
html Tag와 비슷하나, 몇가지 차이 점이 있다.
-
1) 열린 Tag는 반드시 닫힌태그를 가져야 한다. ex) <input type=button > ⇒ X
-
2) 2개 이상 병렬태그는 반드시 감싸는 상위 태그가 있어야 한다.
ex) <div>a</div> <div>b</div> ⇒ X
⇒ <fragment> <div>a</div> <div>b</div> </fragment> -
내부에서 변수 사용은 중괄호를 사용한다.
ex) const name = “hello”;
return ( <div> {name} </div>); -
변수 Scope : var , let, const
기본적으로 변수의 scope는 함수 단위이다. 즉 var를 사용하고, 이후 if/for 블럭에서 var를 동일이름으로 생성하여 생성하면 overwrite 된다.
이것을 피하기 위해서 Block단위 Scope를 사용하기 위해서는 let으로 선언해야 한다.
# Code TEST
아래에서 쉽게 테스트 해 볼 수 있다.
React - CodeSandbox
React example starter project
codesandbox.io
import React, {fragment} from "react";
import ReactDOM from "react-dom";
import "./styles.css";
function App() {
const name = "world";
return (
<fragment>
<div className="App">
<h1> Hello </h1>
<h2> {name} </h2>
</div>
<div> div-2 {name} </div>
</fragment>
);
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
## 조건부 렌더링
{name} 등 바로 렌더링 하는것이 아니라, if 같은 조건에 의하여 발생하는 경우는 어떻게 처리 해야 하는가?
if문을 사용할 수는 없다.
따라서 다음 형식을 이용하여 표현 한다.
1) &&연산자를 이용: <조건식> && <출력식>
2) 삼항식 <조건> ? <correct response> : <incorrect response>
import React, {fragment} from "react";
import ReactDOM from "react-dom";
import "./styles.css";
function App() {
const name = "world";
return (
<fragment>
<div className="App">
<h1> Hello </h1>
<h2> {name} </h2>
</div>
<div> div-2 {name=='world' && 'world correct' } </div>
<div> div-3 {
name == 'hello'
? '헬로우'
: '월드'
} </div>
</fragment>
);
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);