elena-kim / guide-to-react

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Guide to React

이 레포지토리는 React에 대한 기본적인 내용과 GitHub에 앱을 배포하는 방법에 대해 기술한 리포지토리입니다.

더 알아보기 »

Star License Activity
Github Stars License Commits-per-month

Contents


개요

React는 사용자 인터페이스를 만드는 데 사용되는 오픈소스 자바스크립트 라이브러리로, 페이스북에서 개발했습니다. 싱글 페이지 애플리케이션이나 모바일 애플리케이션 개발에 사용될 수 있으며 리액트를 사용하는 회사로는 아래와 같은 곳들이 있습니다.


JavaScript 프레임워크 비교

Angular Vue React
angular.io vuejs.org reactjs.org
Google 개발 (2010년) 전 Google 직원 Evan You 개발 (2014년) Facebook 개발 (2013년)
Angular는 app 개발에 필요한 모든 것을 제공하기 때문에 러닝커브가 상당히 높습니다. TypeScript, MVC 외에도 Angular 내부의 동작 매커니즘과 제공 기술들도 알아야 합니다. Angular와 React보다 상대적으로 배우기 쉽고, 두 프레임워크로부터 Vue로 변경이 쉬운 편입니다. 하지만 Vue의 단순성과 유연성은 잘못된 코드를 허용하여 디버그 및 테스트를 어렵게 만들 수도 있습니다. 가이드 문서가 상당히 잘 되어 있으며, 대부분의 문제도 Stackoverflow에 올라와 있습니다. Angular와 달리 완전한 프레임워크가 아니라서 추가 기능들에 대해 third-party 라이브러리가 필요합니다.

React가 인기있는 이유?

  • 다른 대안보다 덜 복잡하다: React가 발표되었을 당시, 프레임워크로는 Ember.jsAngualr 1.x가 주를 이루었습니다. 하지만 이 두 가지 모두 코드에 너무 많은 규칙을 적용했기 때문에 기존 앱을 이식하는 것이 전혀 편리하지 않았습니다.

    React는 기존 프로젝트에 매우 쉽게 통합되도록 했습니다. 이미 존재하는 코드베이스에 이를 도입하기 위해서는 Facebook에서 그렇게 해야만 했기 때문입니다. 또한, 두 프레임워크는 너무 많은 것을 테이블에 제공했지만, React는 전체 MVC 스택 대신 View 계층만 구현하기로 선택했습니다.

  • 완벽한 타이밍: 당시 Google은 Angular 2.x를 이전 버전과의 비호환성 및 주요 변경사항과 함께 발표했습니다. 하지만 Angular 1에서 2로 이동하는 것은 다른 프레임워크로 이동하는 것과 같았습니다. 따라서 React가 약속한 실행 속도 향상과 함께 개발자가 시도하고 싶어하는 것이 되었습니다.

  • 페이스북의 지원과 리소스: React는 페이스북 앱과 웹사이트, 그리고 인스타그램에서 많이 사용되고 있습니다. 페이스북은 그들의 생산 환경에서 5만여 개가 넘는 React Component를 사용합니다. 또한 React팀은 각 릴리즈에 대한 세부 정보를 지속적으로 제공하는 블로그를 운영중입니다.

    페이스북은 React에 변경사항이 발생할 때마다 변경을 자동화하는 Codemod를 제공하고 있습니다. Codemod란 코드베이스의 변경을 자동화하는 command-line 도구로, React에 변화가 생겼을 때 이전 구성 요소를 새로운 사양으로 자동 대체합니다.


React 특징

  • 선언형(Declarative): React는 선언형 성격에 맞게 컴포넌트(원하는 결과, 뷰)를 얻기 위해 <tag></tag> jsx 문법을 통해 구현합니다. 즉, jsx를 얻기 위한 알고리즘에 대한 구현은 하지 않습니다.

    이와 같은 선언형 특성은, 리액트를 사용할 때 화면 설계라는 초점에 맞춰서 개발할 수 있도록 해주므로, 다른 부분에 대한 고민을 최소화하고 높은 생산성을 보장할 수 있도록 해줍니다.

  • Component 기반: Component는 독립적인 단위의 소프트웨어 모듈을 말합니다. 즉 소프트웨어를 독립적인 하나의 부품으로 만드는 방법을 말하는데요. 리액트는 웹에서 쓰는 각 요소들을 컴포넌트로 만들 수 있게 해 기존의 UI를 다른 화면에서 다시 쓰거나, 다른 프로젝트에서 다시 쓸 수 있도록 하는 장점(높은 재사용성)을 가집니다.

  • Virtual DOM: DOM(Document Object Model, 문서 객체 모델)은 HTML, XML 문서의 프로그래밍 인터페이스입니다. DOM 자체는 빠르지만 요소의 개수가 늘어날수록 CSS 재연산, 레이아웃 구성, 페이지 리페인트의 과정이 반복되면서 성능상 이슈가 발생하게 됩니다. Virtual DOM은 실제 DOM에 접근하여 조작하는 대신에, 이를 추상화시킨 자바스크립트 객체를 구성하여 사용합니다.

    React는 메모리 내에 데이터 구조 캐시를 만들고 결과 차이를 계산한 다음, 브라우저에 표시된 DOM을 효율적으로 업데이트하는데, 이 과정을 재조정(Reconciliation)이라고 합니다. 이를 통해 React 라이브러리는 실제 변경되는 하위 구성요소만 렌더링하게 되고, 성능은 크게 향상됩니다.



개발 준비


명령어

  • 프로젝트 생성

    npx create-react-app <project name>
    
  • 리액트 실행

    npm start
    
    스크린샷 2021-07-27 오후 10 38 05
  • 리액트 종료: ctrl + C

    >> 일괄 작업을 끝내시겠습니까 (Y/N)?
    
  • npxnpm의 차이는?

npx는 execute npm package binaries 의 줄임말로, npm에 속해 있는 npm 패키지 실행 도구입니다. 즉, 새로운 패키지 관리 모듈이 아닌 npm을 더 편하게 사용하기 위한 하나의 도구입니다. npm 버전이 5.2.0 이상이라면 npx가 기본적으로 포함되어 있지만 혹시 설치되어 있지 않다면 아래 명령어로 설치할 수 있습니다.

npm install -g npx

npm은 node package manager 의 줄임말로, Node.js의 기본 패키지 관리자입니다. npm install 명령어를 통해 원하는 패키지를 로컬(node_modules)에 설치할 수 있으며, 패키지 버전을 선택할 수 있기 때문에 패키지 버전 차이로 생기는 문제를 방지할 수 있습니다.


CRA 구조

image

public: Virtual DOM이 들어갈 빈 html이 존재

    - favicon.ico: 페이지 아이콘 이미지 파일
    - index.html: 가상 DOM이 들어가기 위한 빈 html
    - manifest.json: 웹 앱을 다운로드하고 네이티브 앱과 유사하게 제공하기 위해 필요한 정보가 담긴 JSON 파일

src: 리액트 개발이 이루어지는 메인 폴더

    - index.js

import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import registerServiceWorker from './registerServiceWorker';

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

    - App.js

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;

State와 Props

Props State
props는 읽기 전용(read-only)이다 state는 비동기로 변경될 수 있다
props는 수정할 수 없다 state는 this.setState로 수정할 수 있다

  • Props: Props는 Properties의 줄임말로 React 컴포넌트에 전달되는 인수입니다. 컴포넌트는 상속하는 부모 컴포넌트로부터 props를 받고 이 props는 상속받은 컴포넌트 내에서 수정이 불가능합니다. 리액트는 부모 > 자식의 일방향성 상속이라는 특징을 가지기 때문입니다.

    // 'brand' 속성을 'Garage' 컴포넌트에서 'Car' 컴포넌트로 전달하는 예제입니다:
    
    class Car extends React.Component {
      render() {
        return <h2>I am a {this.props.brand}!</h2>;
      }
    }
    
    class Garage extends React.Component {
      render() {
        return (
          <div>
          <h1>Who lives in my garage?</h1>
          <Car brand="Ford" />
          </div>
        );
      }
    }
    
    ReactDOM.render(<Garage />, document.getElementById('root'));
  • State: State는 컴포넌트의 상태를 나타내며, 컴포넌트 내부에서 선언되기 때문에 수정이 가능합니다. state는 외부에 공개하지 않고, 컴포넌트가 스스로 관리합니다. state는 컴포넌트에 속하는 속성값을 저장하는 객체이며, state 객체가 변경되면 컴포넌트도 다시 렌더링됩니다.

    // button을 클릭하면 state인 'hello'의 데이터가 'hello!'에서 'bye!'로 바뀌는 예제입니다:
    
    import React, { Component } from 'react';
    
    class App extends Component {
      state = {
        hello: 'hello!'
      };
    
      handleChange = () => {
        this.setState({
          hello: 'bye!'
        });
      };
    
      render() {
        return (
          <div className="App">
            <div>{this.state.hello}</div>
            <button onClick={this.handleChange}>Click Me!</button>
          </div>
        );
      }
    }
    
    export default App;

Life Cycle

Mounting

  • constructor: 클래스의 기본 특성에 맞게 생성자가 먼저 실행됨
  • render: 렌더링을 위해 작성해 둔 JSX를 리턴하는 메서드 작동
  • componentDidMount: 리액트 코드가 HTML로 변환되어 화면에 나타남

Updating

  • render: 보여주어야 하는 데이터가 업데이트 되면 다시 render 수행
  • componentDidUpdate: 컴포넌트가 업데이트 되었을 때 수행되는 메서드로, prevPropsprevState 인자를 받음

Unmounting

  • componentWillUnmount: 컴포넌트가 사라질 때 수행

Life Cycle 실습 예제


GitHub에 앱 배포하기

1. GitHub Pages를 사용하기 위해 Repository를 생성합니다.

1  create-repo


2. React App을 생성합니다.

npx create-react-app react-sample

3. App 위치로 이동 후 gh-pages npm 패키지를 설치합니다.

npm install --save-dev gh-pages

4. package.json 파일에 아래 내용을 추가합니다.

{
  "homepage": "https://<GITHUB_USER>.github.io/<GITHUB_REPOSITORY_NAME>"
}

<GITHUB_USER><GITHUB_REPOSITORY_NAME> 을 올바른 값으로 대체해야 합니다.

{
  "predeploy": "npm run build",
  "deploy": "gh-pages -b gh-deploy -d build",
}

- predeploy : 애플리케이션 빌드를 생성하기 위해 배포 전에 실행되는 npm 스크립트
- deploy : 빌드 디렉토리의 소스파일을 생성하고 gh-deploy 브랜치로 푸시하는 npm 스크립트

2  package-json


5. npm run deploy 명령을 통해 분기가 저장소에 게시되는 것을 확인합니다.

✅ 정상적으로 게시되었다면 아래와 같이 표시됩니다.
> deploy-test@0.1.0 deploy /Users/yejin/react/deploy-test
> gh-pages -b gh-deploy -d build

Published
❗ 사진과 같은 오류가 나타날 수도 있습니다.

3  deploy-error

이때는 아래 명령을 통해 해결할 수 있습니다.

> git remote add origin <GITHUB_REPOSITORY_URL>.git  
> npm run deploy

<GITHUB_REPOSITORY_URL> 을 앞서 생성한 Repository의 URL로 대체합니다.


6. GitHub 설정에서 branch를 변경해줍니다.

Settings > Pages > GitHub Pages에서 Source 항목의 Branch를 gh-deploy로 변경한 후 저장합니다.

4  branch


7. 앞서 package.json파일에 추가했던 URL로 접속합니다.

5  success


변경사항을 배포할 때는?

App.js 파일을 아래와 같이 변경해보겠습니다.

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>
          My First React!!
        </p>
      </header>
    </div>
  );
}

export default App;

npm run deploy 명령을 실행하면 잠시 후 아래와 같이 업데이트 됩니다.

6  update


❗ 에러

배포 관련해서 발생했던 에러에 대한 내용입니다.

1. npm start입력 시 react-scripts: command not found 에러 메시지 출력

react-scripts 라이브러리를 현재 디렉토리에서 실행시킬 수 없을 때 발생하며, npm install 명령어 입력을 통해 해결할 수 있습니다.

2. 커스텀 도메인 적용 후 npm run deploy 명령 실행 시 도메인이 초기화되는 문제

gh-pages는 기본적으로 [USERNAME].github.io 형식의 도메인을 제공하는데, 설정 페이지에서 도메인을 직접 변경할 수 있습니다.

스크린샷 2021-12-09 오후 10 34 02

하지만 npm run deploy 명령 실행 시 도메인이 자꾸 초기화되는 문제가 발생하는데, 이때는 CNAME 이라는 파일을 추가해줘야 합니다. CNAME 파일은 public 하위에 위치하며, 본인이 적용할 도메인을 내용에 적어줍니다.

스크린샷 2021-12-09 오후 10 46 34

3. 커스텀 도메인 적용 후 리다이렉션 시 404 not found 뜨는 문제

package.json 파일의 build step을 아래와 같이 수정합니다.

스크린샷 2021-12-09 오후 10 52 09

// windows
"build": "react-scripts build && copy build\\index.html build\\404.html"

// macOS
"build": "react-scripts build && cp build/index.html build/404.html"


Reference

📑 reactjs.org
📑 React Tutorial
📑 Web app manifests
📑 The React Handbook
📑 Why You Should Use React.js For Web Development
📑 Angular vs React vs Vue: Which Framework to Choose in 2021
📑 How to deploy your React App to GitHub Pages
📑 Material-UI

About

License:MIT License