본문 바로가기
  • soldonii's devlog
Javascript 공부/Zero To Mastery(-)

(15) 리액트

by soldonii 2019. 8. 27.

*Udemy의 "The Complete Web Developer in 2019 : Zero To Mastery" 강의에서 학습한 내용을 정리한 포스팅입니다.

*https://soldonii.github.io에서 2019년 7월 19일(금)에 작성한 글을 티스토리로 옮겨온 포스팅입니다.

*자바스크립트를 배우는 단계라 오류가 있을 수 있습니다. 틀린 내용은 댓글로 말씀해주시면 수정하겠습니다. 감사합니다. :)


1. 리액트란?

JQuery는 훌륭한 library지만, 각 코드가 다른 코드에 종속되는 dependency의 문제가 심하기 때문에 코드 작성에 많은 어려움을 줄 뿐 아니라, 문제를 tracking하기도 힘들고, 결과적으로 web이 느리게 동작되는 문제를 발생시켰다는 점을 배웠다. 페이스북이 만든 React는 이러한 문제들을 해결해주었다. React는 우리가 보는 web 화면, 즉 DOM을 예상 가능한 범위 내에서 쉽게 변경할 수 있도록 도와주고, 관리하기 용이하게 해준다. 또한 React는 web 뿐 아니라, 모바일, desktop app, VR 등 어디에나 이용할 수 있다.

 

현재까지는 1개의 html 파일, 1개의 javascript 파일, 1개의 css 파일을 이용해서 website를 만들었다. 하지만 아래 사진처럼 작은 component들로 website를 만든다면 훨씬 더 편하지 않을까? 한 개의 atom을 만들고, 이를 활용하여 하나의 molecule을 만든다면 만들어 놓은 component을 가져다 쓰기만 하면 해당 기능을 이용할 수 있게 된다.

 

출처 : https://www.udemy.com/the-complete-web-developer-zero-to-mastery/

 

# 일방향(One Way Data Flow)

React에서 데이터의 흐름은 일방향이다.(One Way Data Flow) 즉, 특정 component(ex. 사진 속 푸른 점 중 하나)에 변화가 발생해도, 해당 component의 부모는 이를 알지 못하고 알 필요도 없다.

출처 : https://www.udemy.com/the-complete-web-developer-zero-to-mastery/

 

# 가상 DOM(Virtual DOM)

프론트엔드 개발자의 중요한 역량 중 하나는, DOM Manipulation을 최소화하여 구동속도를 빠르게 하고 동시에 bug를 최소화 하는 것이다. React 이전의 우리는 화가와 같았다. 어떤 element를 선택할 것인지, 이를 어떻게 바꿀 것인지 등 모든 것을 일일이 지정해주어야 했다.

그러나 React는 하나의 bot과 같다. 우리가 다루고자 하는 대상이 무엇인지만 알려주면, React가 가장 최적화된 방식으로 작업을 수행해주게 된다.(무슨 의미인지 아직 실습은 안해보아서 와닿지는 않는다…)

출처 : https://www.udemy.com/the-complete-web-developer-zero-to-mastery/

 

# 리액트 생태계(Eco-System)

React가 구동되기 위해 함께 사용되는 library가 많이 있다. 가장 최신 library, Javascript 개발자들이 많이 사용하는 기술을 활용함으로써 Javascript에 훌륭한 생태계를 구축하고 많은 문제들을 해결해나가고 있다.

출처 : https://www.udemy.com/the-complete-web-developer-zero-to-mastery/

 

2. Create-React-App

앞서 NPM 패키지는 local과 global로 설치할 수 있다고 했는데, global로 설치해보자. npm install -g create-react-app 명령어로 react-app 패키지를 내 컴퓨터에 설치할 수 있다. create-react-app {project name} 명령어로는 react-app 패키지가 local로 설치된 project name 폴더가 생성된다.

 

  • “dependencies” 내의 "react-scripts" 를 통해, browserify, webpack을 이용해 bundle.js 같은 파일을 통합하는 작업을 더 이상 할 필요가 없어졌다.(? 무슨 말일까 나중에 다시 확인해보자.) “scripts” 내의 "eject" 는 react 내에서 나온 후, 내 방식대로 customizing 하도록 돕는 기능이다.
  • “package-lock.json” 파일은 package.json에 의해 자동 생성되는 파일로, 내 패키지의 version이 자동적으로 lock된 상태로 기록되어 있는 파일이다.
  • “.gitignore” 파일은 github에 push할 때 포함되지 않아야 하는 폴더, 파일 등을 기록해놓은 파일이다.

ReactDOM.render(<*App* />, document.getElementById('root'));  root 라는 Id를 가진 element를 선택한 후,App component를 rendering하겠다는 의미이다.

 

 

만일 create-react-app 버전이 업데이트 되어서 새로운 버전으로의 업데이트가 필요할 경우에는 어떻게 할까? 아주 간단하다.

  1. 작업 중인 project 디렉토리의 package.js 파일을 연다.
  2. "dependencies" 에서 "react scripts" 부분의 버전을 새로운 버전으로 수정한다.
  3. terminal에서 npm install을 입력한다. ⇒ 업데이트가 필요한 부분을 자동으로 설치할 것이다.

 

3. 컴포넌트 만들기

React에서는 어떻게 important 키워드를 사용하는 것이 가능할까?

React 패키지에 webpack이 포함되어 있기 때문에, browserify를 사용하지 않아도 require 대신 최신 syntax인 import키워드를 사용할 수 있다.

 

React와 ReactDOM의 차이는?
// index.js 파일 내에...
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import * as serviceWorker from './serviceWorker';
import 'tachyons';

ReactDOM.render(<App />, 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();

React는 view를 만들기 위한 library다. 즉, 앞서 말했던 react bot과 같은 역할을 한다. 우리를 위해 DOM manipulation을 해주는 역할을 한다. 반면 ReactDOM은 UI를 browser에 실제로 rendering할 때 사용되는 library로, React와 DOM을 연결시켜주는 glue 같은 역할이다.(cf. ReactNative는 React와 mobile device를 연결시켜주는 glue이다.)

serviceWorker.unregister(); 는 offline에서도 파일을 사용할 수 있게 해주는 역할을 하지만, 현재로서는 크게 의식하지 않아도 된다.

 

ReactDOM.render(<App />, document.getElementById('root')); 가 여기에서 가장 핵심적인 코드이다. 해석해보자면, ReactDOM 패키지가 괄호 안에 들어있는 내용을 webpage에 rendering 해주길 요청하는 내용이다. 괄호 안의 내용은 “App”이라는 Javascript 파일이 rendering할 대상이라는 것이다.

component를 새로 만들 때, 파일명 앞글자는 대문자로 작성하는 것이 표준이다.

 

# Hello.js라는 component를 만들어보자.

import React from 'react';
import "./Hello.css";

function Hello() {
  return (
  <div className="f1 tc">
    <h1>Hello World</h1>
    <p>Welcome to React</p>
  </div> 
  )
}

export default Hello;

 

가장 먼저 할 것은 필요한 component들을 본 파일로 import하는 것이다. react 파일로부터 React를 import한다. 그리고 다른 파일에서 Hello component를 이용할 수 있도록 마지막에 export도 잊지말자. React는 마치 HTML 같은 양식을 return할 수 있는데, 여러 줄을 return할 경우에는 () 로 묶어준다.

CSS 서식도 개별적으로 적용할 수 있으나, 더욱 쉽게 CSS Styling을 도와주는 “tachyons” library를 이용해보자.

 

# tachyons?

website 만들 때 “bootstrap”으로 기본적 layout 및 component를 쉽게 이용할 수 있었다. 마찬가지로 “tachyons”에 미리 설정된 class name을 부여함으로서 아주 쉽게 CSS Styling을 적용할 수 있다.

npm install tachyons 로 설치하고, import tachyons 로 index.js 파일에 tachyons를 import한다. 이제 div에 className="f1 tc" 와 같이 class명만 부여하면 미리 정의된 CSS 서식을 사용할 수 있다.

 

 tachyons.io : 자세한 서식은 사이트에서 확인 가능하다.

 

# JSX

위 코드를 살펴보면, class를 설정할 때 class 키워드 대신 className 키워드를 활용했다.  어떻게 html 코드를 Javascript 파일 안에 포함시킬 수 있을까? 이는 JSX가 html과 유사하게 생긴 문법들을 Javascript 파일에 포함시키는 것을 가능하게 했기 때문이다. 그러나 여기서 몇 가지 의문이 발생할 수 있다.

 

1. separtion of concerns 문제가 발생하지 않을까?

React는 html, css, javascript가 따로 분리되는 개념이 아니라, 세 요소가 어우러진 하나의 component를 small universe처럼 취급한다. 즉, 완성된 component 별로 관리하는 개념이다. 패러다임이 바뀐 것이다.

 

2. Javascript 파일 내에서 HTML 코드는 어떻게 활용되는 걸까?

정확히 말하자면, html 코드 같아 보이지만 실제 html 코드는 아니다. 다만 JSX를 통해 html 같아 보이는 이 코드들이 virtual DOM을 만들고, 실제 DOM 대비 어떤 부분에 변화가 생겼는지를 비교한다. React는 이러한 방식으로 DOM Manipulation을 진행하고, 그렇기 때문에 React가 굉장히 빠르게 작동하는 library인 것이다. 변화가 필요한 부분만 비교해서 변화시키기 때문이다.

 

결국 class를 설정할 때 class 키워드 대신 className 키워드를 활용하는 것은, 이 파일이 HTML 파일이 아니라, HTML 코드를 Javascript 파일 안에 붙여서 읽을 수 있도록 도와주는 JSX 문법을 활용하는 Javascript 파일이기 때문이다. 알다시피, Javascript에서 class 키워드는 새로운 class를 설정할 때 사용되는, 이미 built-in으로 설정된 명령어이다. 따라서 class 키워드를 사용하는 것은 불가능하고, 대신 className 키워드로 html 코드에 class를 부여하는 것이다.

 

React는 property를 부여하는 것이 가능하다.
// index.js 파일
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import Hello from './Hello';
import * as serviceWorker from './serviceWorker';
import 'tachyons';

	// property 부여
ReactDOM.render(<Hello greeting={'Hello' + 'React Ninja'}/>, document.getElementById('root'));

 

불러올 대상(Hello)에 greeting이라는 property를 부여했다.

// Hello.js 파일
import React { component } from 'react';
import "./Hello.css";

class Hello extends Components {
  render() {
    return (
      <div className="f1 tc">
        <h1>Hello World</h1>
        <p>{this.props.greeting}</p>
      </div> 
      );
	}
}

export default Hello;

 

index.js 파일에서 불러오고자 하는 Hello에 greeting이라는 property를 부여함으로써, Hello.js 파일 내에서 greeting이라는 property를 사용할 수 있게 되었다. html에서 class, id 등을 지정해주는 것과 비슷한 개념이라고 한다..

// Hello.js 파일
import React { component } from 'react';
import "./Hello.css";

const Hello = (props) => {
  return (
      <div className="f1 tc">
        <h1>Hello World</h1>
        <p>{props.greeting}</p>
      </div> 
  );
}

export default Hello;

 

그리고 class로 object를 생성하는 방식은 바로 위 코드, 즉 단순히 함수를 생성해서 return 시키는 행위와 동일하다고 볼 수 있다. 이 경우에는 Hello는 객체가 아니라 함수이므로, this 키워드는 필요하지 않다.(무슨 말인지 잘 모르겠음…)

댓글