ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • React.js(1)_React란?
    SPA/React.js 2022. 9. 28. 10:21

    해당 게시글은 2022.04.28에 깃허브로 작성되었습니다.

     


     

    1. React란?

    React는 페이스북이 만든 사용자 UI 구축을 위한 자바스크립트 라이브러리 이다.

    라이브러리(Library)란?
    라이브러리를 한마디로 정의하자면 쉬운 개발을 위해 기능을 제공하는 도구의 모음이다.

    (+) 프레임워크란?
    여기서 자주 헷갈리는 프레임워크(Framework)와의 차이점에 대해서 짚고 넘어가려 한다.

    프레임워크(Framework)는 Frame + Work 의 합성어로,
    말 그대로 특정 프로그램을 개발하기 위한 여러 요소들과 메뉴얼인 룰을 제공하는 프로그램이다.
    라이브러리와의 가장 큰 차이점은 자유도이다.

     

    사용자 UI와 같은 프론트엔드 진영에서는 3개의 라이브러리or프레임워크가 경쟁 중인데

    바로 Angular, React, Vue 이다.

    이 중에서 우리는 React에 집중할 것이다.

    우선 간단하게 React의 가장 큰 특징들부터 알아보자.

     


     

    2. React의 특징

    (1) JSX 문법

    JSX는 Javascript 안에서 HTML 문법을 사용해서 view를 구성할 수 있게 도와주는 Javascript 문법이다.

    class HelloMessage extends React.Component {
      render() {
        return (
          <div>
            Hello {this.props.name}
          </div>
        );
      }
    }

    위 코드가 JSX 문법이다.

    보다시피 HTML 문법과 Javascript 문법이 혼재돼 있다는 걸 알 수 있다.

     

    (2) Component 기반

    개인적으로 React의 가장 큰 특징이라고 생각하는 Component는

    페이지의 화면을 구현할 때 요소를 여러 부분으로 분할하여 생성함으로써 코드의 재사용성과 유지보수성을 대폭 증가시켜준다.

     

    예를 들어 아래와 같은 navigation이 있다고 가정해보자.

    <ul>
      <li><a href = '/create'>create</a></li>
      <li><a href = '/update'>update</a></li>
      <li><a href = '/delete'>delete</a></li>
    </ul>

    이 navigation은 하나의 페이지에서만 사용되는 것이 아닌, 수백 개의 페이지에서 사용되는데

    갑자기 createmain으로 변경해달라는 요청이 왔다고 가정했을 때

     

    우리는 수백 개의 html을 열어 모든 create를 main으로 변경하는 수고로운 작업을 해야 한다.

     

    그러나 React의 Component를 활용하여 해당 navigation을 Nav라는 Component로 따로 제작하고 이를 각 페이지에 <Nav></Nav>라는 태그로 불러올 수 있다면,

    우리가 Nav Component 속 create를 main으로만 바꿔줘도 자동으로 수백 개의 페이지에 적용된다.

     

    (3) Virtual DOM

    가상 DOM(Virtual DOM)은 기존 DOM의 한계를 벗어나기 위해 나온 대안이다.

     

    DOM의 구조는 트리 구조로 되어 있어 만약 프로그래머가 어떤 DOM의 요소를 하나 수정하는 함수를 만들고 실행한다면,

    렌더트리를 재생성하고 모든 요소의 스타일이 다시 계산되고 레이아웃을 만들고 페인팅을 하는 일련의 과정이 다시 반복된다.

     

    그로 인해 불필요한 연산이 매번 일어나는 불상사가 일어나곤 한다.

    이를 해결하기 위해 가상 DOM이 등장하게 된 것이다.

     

    가상 DOM은 변화를 가상 DOM에서 미리 인지해 변화시키는데 말 그대로 실제 DOM이 아닌, 가상의 DOM이기에

    렌더링도 되지 않고 연산 비용이 비교적 실제 DOM보다는 적다.

    가상 DOM을 통해 인지한 변화는 마지막에 실제 DOM에 전달함으로써, 모든 변화를 한번에 렌더링하게 되는 것이다.

     

    개인적으로 제일 잘 설명했다고 생각하는 유튜브 링크를 첨부한다.

     


     

    3. React Project 생성

    그럼 긴 말 않고 이제 React Project를 생성하고 직접 코딩을 해보며 익혀보는 시간을 가져보자.

    우선 들어가기 전에 Node.js가 준비되어 있어야 한다. 아래 링크로 들어가 Node.js를 설치하자.

     

    Node.js

    Node.js® is a JavaScript runtime built on Chrome's V8 JavaScript engine.

    nodejs.org

     

    설치가 완료되었다면 설치가 잘 되었는지 확인하기 위해 명령 프롬프트를 사용해보자.

    1. window + r을 눌러 실행을 실행시키고
    2. cmd를 입력한다.
    3. 해당 창에 node -v를 입력 후 엔터를 치면 아래와 같이 설치된 node의 버전이 나오는데 그럼 무사히 설치된 것이다.

     

    node가 잘 설치되었다면 React 코딩을 진행할 폴더를 생성해주고 본인이 사용하는 코드 에디터에 해당 폴더를 열어준다.

    그 후 터미널을 열어 npx create-react-app . 이라고 입력 후 엔터를 치면 해당 폴더에 React 프로젝트를 위한 여러 모듈과 파일들이 생성된다.

    npx create-react-app .현재 위치하고 있는(열려 있는) 폴더 내에 react-app을 설치한다는 의미이다.

     

    폴더 내에 새 폴더를 만들어 생성하고 싶으면 아래와 같이 폴더명을 입력하면 된다.

     

    여기서 npx란?
    - npx
     임시로 프로그램을 설치하여 한번만 실행시키고 지우는 명령어

    - npm
     프로그램 자체를 설치하는 명령어
     즉, npx는 컴퓨터 공간을 낭비하지 않고 실행할 때마다 설치를 새로 다운로드하기에 항상 최신 상태라는 장점이 있다.

     

    설치가 완료된 후, 터미널에 npm run start를 입력하면,

    약간의 로딩 후 아래와 같은 페이지가 나타나게 되는데 react를 다루는 동안 계속 보게 될 기본 페이지다.

     

    본격적으로 코드를 작성하기 전, 더 편하게 React를 진행할 수 있는 도구를 설치해보자.

     

    react_developer_tool에 접속해 React Developer Tools 확장 프로그램을 다운받고 React 페이지에서 개발자 도구를 키면 상단에 Components라는 탭이 새로 생기고

    아래와 같이 Component 단위별로 나눠서 확인이 가능해진다.

     

    그럼 다시 코드 에디터로 돌아와 각 폴더들의 역할에 대해 알아보자.

    (1) public

    앞서 말했듯 React는 가상 DOM을 사용하기에 가상 DOM이 들어갈 빈 껍데기 html이 필요한데 해당 html이 존재하는 폴더이다.

    (2) src

    React 개발이 이루어지는 메인 폴더이다.

     


     

    4. React 기초 문법 및 규칙

    우선 코드를 쳐보며 직접 배워나가고 마지막에 요약하며 정리하는 방식으로 진행하자.

    src 폴더 내에 있는 파일 중 App.js, index.js를 제외하고 다른 파일들은 모두 지운다.

     

    그럼 아래와 같은 폴더 구조를 갖게 될 것이다.

     

    쉬운 코드 작성을 위해 Extension 메뉴에서 React/Redux/React-Native snippets를 검색하여 다운로드해준다.

    해당 extension을 설치하면 코드 작성 시 rcc + tab만으로도 React Component 기본 작성이 완료된다.

     

    위에서 언급했던 Component는 react 모듈에서 가져와야(import) 사용이 가능하므로

    import React, { Component } from 'react' 로 import를 해야 한다.

     

    Component는 Class를 이용해 사용하게 되는데

    여기서 export default란 다른 파일에서도 현재 작성 중인 Component를 사용 가능하도록 연결해주는 역할이라고 보면 된다.

    default를 안 붙이게 된다면 아래와 같이 import 태그에서 { } 안에 Component명을 넣음으로써 연결해줄 수 있다.

    import {Home} from './components/Home';

     

    Component는 기본적으로 아래와 같은 형식을 갖고 있다.

    render 함수를 호출하고 그 속에 return값으로 JSX문법을 이용하여 화면에 나타날 요소들을 작성해주는 형식이다.

      render() {
        return (
        )
      }

     

    이어서 React를 다룰 때 가장 중요한 개념인 propsstate에 대해서 배워보자.

     

    (1) state

    state는 하나의 Component가 가질 수 있는, 변경 가능한 데이터이다.

    Component를 렌더링할 때 새로운 데이터를 생성해야 하거나 기존의 데이터를 참고해서 새로운 데이터를 만들어야 할 때 사용 가능하다.

     

    아래 예제를 통해 state에 대해 이해해보자.

    // src/App.js
    import React, { Component } from 'react'
    
    export default class App extends Component {
      state = {
        hello: 'hello app js!'
      };
      render() {
        return (
          <div className='App'>{this.state.hello}</div>
        )
      }
    }

    위와 같이 Component 내에 state를 생성하고 return 값에서 호출해보자.

     

    state는 render 함수 호출 전에 생성하며 객체로 작성한다.

    또한 return 안에서는 JSX 문법에 따라 {} 안에 변수를 작성해야 한다.

    this.state.hello는 해당 Component(this)의 state의 hello의 값을 가져오겠다는 의미이다.

     

    이제 위에서 설정한 state의 값을 변경해보자.

    // src/App.js
    import React, { Component } from 'react'
    
    export default class App extends Component {
      state = {
        hello: 'hello app js!'
      };
    
      handleChange = () => {
        this.setState({
          hello: 'bye app js!'
        });
      };
    
      render() {
        return (
          <div className='App'>
            <div>{this.state.hello}</div>
            <button onClick={this.handleChange}>click me!</button>
          </div>
        )
      }
    }

     

    state는 우리가 Javascript를 작성하던 방식처럼 대입해서(state.hello = "bye app js!") 변경할 수 없다.

    그렇게 바꿔도 React는 우리가 대입한 값을 인식하지 못하기 때문에 반드시 setState({})를 이용해서 변경해야 한다.

     

    한 가지 유의할 점은 HTML에서는 onclick으로 작성했지만 React 내에서는 onClick처럼 camelCase 방식으로 작성해야 한다.

     

    (2) props

    props에 대해 자세히 알아보기 전에 state와 props이 차이점에 대해 명확히 짚고 넘어가자.

    1. state는 현재 Component 내에서 변경이 가능하다.
    2. props는 현재 Component 내에서 변경이 불가능하다.
    3. props와 state 모두 하위 Component에 상속이 가능하다.

     

    아래 코드를 보면 message라는 변수를 App Component가 props로 사용할 수 있게 전달(상속)하고 있다.

    // src/index.js
    import React from 'react';
    import ReactDOM from 'react-dom/client';
    import App from './App';
    
    const root = ReactDOM.createRoot(document.getElementById('root'));
    root.render(
      <React.StrictMode>
        <App message="Hello Message"></App>
      </React.StrictMode>
    );

     

    이렇게 받은 문자열을 App Component 내에서 아래와 같이 사용할 수 있다.

    // src/App.js
    import React, { Component } from 'react'
    
    export default class App extends Component {
      state = {
        count: 0
      };
    
      handleChange = () => {
        this.setState({
          count: this.state.count + 1
        });
      };
    
      render() {
        return (
          <div className='App'>
            <div className='props'>
              <span>{this.props.message}</span>
            </div>
    
            <div className='state'>
              <div>{this.state.count}</div>
              <button onClick={this.handleChange}>count up!</button>
            </div>
          </div>
        )
      }
    }

    해당 Component(this)가 props로 받은 message 변수를 사용한다는 의미이다.

     

    추가적으로 props를 절대 변경할 수 없는 것은 아니다.

    // src/App.js
    import React, { Component } from 'react'
    
    export default class App extends Component {
      state = {
        count: 0
      };
    
      handleChange = () => {
        this.setState({
          count: this.state.count + 1
        });
      };
    
      render() {
        return (
          <div className='App'>
            <h3>index Props</h3>
            <div className='props'>
              <span>{this.props.message}</span>
            </div>
    
            <h3>State</h3>
            <div className='state'>
              <div>{this.state.count}</div>
              <button onClick={this.handleChange}>count up!</button>
            </div>
    
            <h3>App Props</h3>
            <div className='inside-app-props'>
              <InsideApp
                count={this.state.count}
                handleChange={this.handleChange}
              />
            </div>
          </div>
        )
      }
    }
    
    class InsideApp extends Component {
      render() {
        return(
          <div>
            {this.props.count}
            <button onClick={this.props.handleChange}>click me!</button>
          </div>
        )
      }
    }

    위와 같이 InsideApp Component의 propsstate를 넘겨줌으로써 state가 변경됨에 따라 props 또한 변경되도록 처리한다.

     

    [요약]
    1. JSX 문법으로 작성하므로 소문자로 시작하면 HTML 문법과 혼동되기 때문에 Component 이름은 대문자로 시작하여 작성한다.
    ex) Nav

    2. extension이 설치되어 있다면 rcc + tab만으로도 React Component 기본 작성이 완료된다.

    3. rcc의 기본 구조는 아래와 같다.
    import React, { Component } from 'react'
    
    export default class App extends Component {
      render() {
        return (
        )
      }
    }​


    4. state는 하나의 Component가 가질 수 있는, 변경 가능한 데이터
    현재 Component 내에서 setState({})를 이용해 변경이 가능하다.

    5. props는 현재 Component 내에서 변경이 불가능하다.

    6. props와 state 모두 하위 Component에 상속이 가능하다.

     


     

    5. 생명 주기-LifeCycle

    이제 React에 대해 기본적인 내용은 숙지하게 되었다.

    그럼 이제 응용을 하며 추가적인 사항들을 배워나가면 되는데 그 중에서 꼭 알아야 하는 게 생명 주기(LifeCycle)이다.

     

    예를 들어보자.

    Component가 렌더링된 직후, setState를 하고 싶다면 어디에 해당 로직을 작성해야 할까?
    Component가 업데이트된 직후, 어떤 부분이 업데이트되었는지 체크하고 싶다면 어디에 해당 로직을 작성해야 할까?

     

    위와 같은 상황에서 생명 주기를 알고 있다면 쉽게 코드를 작성할 수 있다.

    위 이미지가 React의 생명 주기에 대해 설명한 표다.

    크게 나뉘는 부분들을 기준으로 설명하자면

     

    (1) Mounting: React 코드 첫 렌더링의 시작

    Component가 처음 실행될 때, 그것을 Mount 라고 표현한다.

     

    Component가 시작되면 우선 context, defaultProps와 state를 저장한다.

    그 후에 componentWillMount 메소드를 호출한다.

    그리고 render로 Component를 DOM에 부착하여 Mount가 완료된 후 componentDidMount가 호출된다.

     

    주의할 점은 componentWillMount에서는 Mount 중이기 때문에 props나 state를 바꾸면 안된다.

    또한 아직 DOM에 render하지 않았기 때문에 DOM에도 접근할 수 없다.

     

    반면에 componentDidMount에서는 render가 완료됐기 때문에 DOM에 접근할 수 있다.

    그렇기에 여기에서 주로 AJAX 요청을 하거나 setTimeout, setInterval 같은 행동을 한다.

     

    정리하자면 아래와 같은 순서로 실행된다.

    1. state, context, defaultProps 저장
    2. componentWilMount
    3. render
    4. componentDidMount

     

    (2) Updating: React의 props나 state가 업데이트되었을 때

    Component가 가지고 있는 props나 state가 업데이트될 때에 수행되는 부분이다.

    - setState 메소드
     state를 업데이트하려면 반드시 setState를 수행해야 하기에 React는 해당 메소드가 수행되었을 때 Component를 업데이트한다.

    - props가 업데이트되었을 때 부모 Component에서 setState를 수행하여 현재 Component가 가지고 있는 props가 업데이트되었을 때에 React Component를 업데이트한다.

     

    업데이트 과정은 다음과 같다.

     

    componentWillReceiveProps 메소드가 호출되고 그 후에 shouldComponentUpdate, componentWillUpdate가 차례대로 호출된 후,

    업데이트가 완료(render)되면 componentDidUpdate가 된다.

    해당 메소드들은 첫번째 인자로 prevProps와 prevState를 받아

    현재 업데이트된 props | state와 업데이트되기 전 props | state를 비교해서 원하는 작업을 수행할 수 있다.

     

    shouldComponentUpdate에서는 아직 render하기 전이기 때문에 return false를 하면 render를 취소할 수 있다.

    이를 통해 쓸 데 없는 업데이트가 일어나면(변경사항이 없을 시에는 render를 하지 않도록) 걸러냄으로써 성능 최적화를 할 수 있다.

     

    주의할 점은 componentWillUpdate에서는 state를 바꾸면 안 된다.

    아직 props도 업데이트되지 않은 시점이므로 state를 바꾸면 또 shouldComponentUpdate가 발생한다.

    반면에 componentDidUpdate에서는 render가 완료되었기 때문에 DOM에 접근할 수 있다.

     

    요약하자면 아래와 같다.

    1. componentWillReceiveProps
    2. shouldComponentUpdate
    3. componentWillUpdate
    4. render
    5. componentDidUpdate

     

    (3) Unmounting: Component가 제거될 때

    더는 Component를 사용하지 않을 때 componentWillUnMount가 발생한다.

     

    (+) Error: 에러가 발생했을 때

    에러 발생 시를 위한 componentDidCatch도 있다.

    componentDidCatch(error, info) {
      console.error(error, info);
    }

    위와 같이 사용하고 최상위 Component에 한 번만 넣어주면 된다.

     

    (+) getDerivedStateFromProps

    props가 바뀌면 그에 따라 state도 같이 바뀐다.

    예를 들어 props.a가 10이고 derivedA state를 props.a의 10배로 설정해두었다면 derivedState는 기본적으로 100이 된다.

     


     

    6. 배포

    React 프로젝트를 다 완성하면 사용자들이 사용할 수 있도록 공유가 가능하도록 해야 하는데 이런 과정을 배포(Deploy)라고 한다.

    배포 방식은 크게 두가지로 나뉘는데 우선 로컬 서버로 진행하는 방법을 알아보자.

     

    (1) 로컬 서버로 배포

    이를 위해서는 빌드(build)라는 과정이 필요한데 아래와 같은 코드를 터미널에 입력하면 된다.

    npm run build

    이후에 디렉토리 구조를 보면 build라는 폴더가 생긴 걸 확인할 수 있다.

    위 과정을 통해 실 서버 환경이 완성되었다.

    그럼 이제 아래 명령어를 통해 웹 서버로 빌드된 앱을 실행해보자.

    npm install -g serve

     

    [여기서 -g란?]
     global의 약자로 현재 사용 중인 컴퓨터 어디에서나 해당 명령어를 사용할 수 있게 해준다.

     

    그 다음에는 생성된 build 디렉토리를 Document Root로 지정해주는 명령어를 실행해보자.

    npx serve -s build

     

    그럼 위와 같이 접속 가능한 주소가 뜨고 해당 주소를 통해 접속해주면 된다.

     

    (2) 깃으로 배포

    (2-1) Git과 React 프로젝트 연결

    Git이 설치되어있다는 전제 하에 진행한다.

    git remote add origin https://github.com/(개인 레포지토리 주소)
    git push -u origin master

    터미널창에 위와 같이 작성하여 Git과 React 프로젝트를 연결해준다.

     

    (2-2) Git Branch 설정

    그 후, Git Branch 중 master Branch를 선택한 후 save해준다.

    이 과정이 있어야 우리가 작성한 모든 파일을 기반으로 React 프로젝트 페이지가 실행될 수 있다.

     

    (2-3) gh-pages 라이브러리 설치

    Git Branch에 gh-pages를 추가하기 위해 아래 코드를 입력함으로써 라이브러리를 설치한다.

    npm install gh-pages --save-dev
    [gh-pages란?]
     React 프로젝트를 쉽게 배포할 수 있도록 Github Pages에서 제공하는 라이브러리.

    해당 Branch로 빌드하면 위에서 진행했던 git push -u origin master로 인해 모든 소스 코드들은 master Branch 내에 존재 하고
    이를 기반으로 웹사이트 내에서는 build 폴더만 보여지게 함으로써 코드의 보안성과 용량 문제를 해결해줄 수 있다.

    일반적인 Branch를 사용하지 않는 이유는 기존의 Branch로는 아래와 같이 우리가 만들 React 웹을 읽어들일 수 없기 때문이다.

     

    (2-4) package.json 설정

    package.jsonscripts 내부에 deploy 명령어를 정의하고

    연결할 homepage 주소를 정의하면 자동으로 해당 깃주소와 연결해준다.

    // package.json
      "scripts": {
        "start": "react-scripts start",
        "build": "react-scripts build",
        "test": "react-scripts test",
        "eject": "react-scripts eject",
        "deploy": "gh-pages -d build"
      },
      "homepage": "https://rlacodud.github.io/TodoList/",
      "eslintConfig": {

     

    (2-5) npm run deploy

    npm run deploy를 입력하여 배포를 실행시킨다.

     

    (2-6) gh-pages 설정

    그 후, Git Branch 설정을 gh-pages 설정 후 저장하면 해당 주소에서 우리가 만든 React 프로젝트를 확인할 수 있다.

     


     

    이렇게 React만을 사용할 때 알아야 하는 사항에 대해 배워봤다.

    다음에는 주소에 따라 화면을 바꿔주는 React-Router에 대해 알아보자.

     

    'SPA > React.js' 카테고리의 다른 글

    [React] Firebase로 회원가입/로그인, 로그아웃  (0) 2022.10.26
    React.js(5)_React Redux  (0) 2022.09.28
    React.js(4)_React Ajax  (0) 2022.09.28
    React.js(3)_Ajax  (0) 2022.09.28
    React.js(2)_React Router  (0) 2022.09.28
Designed by Tistory.