React(intro)

JH Cho·2022년 8월 29일
0

React

목록 보기
7/27

정리
1. 어떠한 흐름으로 오늘날 React가 많이 사용되고 있는지 설명할 수 있다.
2. React가 무엇인지 정의할 수 있다.
3. Component의 개념과 종류에 대해 설명할 수 있다.
4. JSX에 대한 정의와 기본 특성에 대해 설명할 수 있다.
5. CRA를 설치하고 폴더와 파일이 어떻게 구성되어 있는지 설명할 수 있다.


Web Application

  • 웹 애플리케이션 : 유저가 별도의 사용 소프트웨어(어플리케이션)를 설치하지 않아도 웹 브라우저만를 통해 소프트웨어의 기능을 이용할 수 있도록 만든 웹 서비스를 웹 어플리케이션이라고 한다.

    웹이 복잡성이 증가함에 따라 바닐라 자바스크립트만으로는 한계에 도달했고 DOM조작을 쉽게 해주는 라이브러리인 JQuery가 나왔음. 하지만 DOM에 접근해서 직접 조작하는 메서드 모음에 불과해서 한계가 있었음.

Framework와 Library

  • 프레임워크와 라이브러리는 공통적으로 개발을 효율적이고 편리하게 하기 위해 미리 개발자들이 만들어 둔 코드이다.
    하지만 프레임 워크는 다른 사람이 만들어둔 frame 내에서만 수동적으로 작업을 해야하고 라이브러리는 개발자가 능동적으로 필요한 기능(라이브러리)를 찾아 사용할 수 있다는 점이 차이이다.

  • 예시 ) 개발을 요리에 비유
    프레임워크 : 여러 도구가 준비된 주방 안에서 정해진 도구만을 사용.

    다른 사람이 만들어 놓은 도구를 내 입맛에 맞게 가져와 사용 가능.

  • 앵귤러와 뷰는 프레임워크이고 리액트는 라이브러리지만 프레임워크적인 특징을 일부 가지고 있음.

React를 사용하는 이유

리액트는 자바스크립트의 문법을 그대로 활용하기 때문에 자바스크립트에 친숙하다면 금방 적응이 가능하다. 또한 메타(페이스북)의 지속적 관리와 함께 사용자가 가장 많기도 하다. 또한 리액트를 사용하는 개발자는 리액트 기반의 리액트 네이티브라는 기술을 통해 ios, 안드로이드 기반의 모바일 어플도 개발이 가능하다.

React의 정의 & 특성

React를 사용하는 가장 큰 이유 중 하나는 UI를 자동으로 업데이트 해준다는 점이다.

  • 우리는 데이터 기반의 선언적 개발이 가능해지고 자동으로 UI를 업데이트 하는 과정에서 Virtual DOm을 통해 최적화된 업데이트를 할 수있다.
  • Component 기반의 개발을 통해 복잡한 UI를 효과적으로 구성 가능
  • JSX 문법으로 컴포넌트를 편리하게 작성 가능.

react의 특징

선언적

선언적 개발(무엇을 해결할래?) <-> 절차적 개발(문제를 "어떻게" 해결할래?)

  • 예시)
    선언적(리액트) : 원하는 결과를 선언/DOM 조작은 React에위임
    절차적(바닐라) : 자바스크립트로 직접 DOM을 조작하는 방식

Virtual DOM

리액트에서 UI 업데이트 할 때는 "어떻게"하는 지에 대한 중간과정 처리를 위해 DOM요소에 변화를 주기 전에 내부의 가상 DOM을 통해 실제 DOM에 일어나야 하는 변화를 계산함.

왜?

화면 업데이트 과정 : DOM 요소에 변화 발생 -> 웹 브라우저는 렌더트리(DOM트리 + CSSOM 트리)와 레이아웃 위치를 계산하고 화면에 그리는 작업을 수행

현대의 복작하고 규모가 큰 웹 어플은 상호작용이 많아 DOM 조작이 많기 때문에 이전 UI 상태를 메모리에 유지하는 가상 DOM을 통해 UI의 최소 집합을 계산하여 DOM 처리 횟수를 최소화하고 효율적으로 진행. 결과적으로 웹브라우저 내의 연산량 감소시키고 성능 저하를 개선시킴.

Component

  • 정의
    프론트 엔드에서의 컴포넌트는 재활용 가능한 UI 구성 단위
    컴포넌트 : 레고 블럭 / 여러 컴포를 조합해 새로운 UI를 만들거나 동일 컴포를 여러번 사용해 UI를 조립할 수 있음.

컴포넌트의 특징

  1. 필요한 곳에서 재사용 가능

  2. 독립적 사용이 가능하여 코드 유지보수에 좋음.
    위 이미지의 에 있는 커리큘럼의 공통적 스타일 혹은 내용을 변경하려면 컴포넌트만 수정하면 됨.

  3. 또 다른 컴포넌트 포함 가능
    컴포넌트는 또 다른 컴포넌트를 포함하여 구성 가능
    는 자식 컴포이며 , 를 포함한 부모 컴포넌트.

  4. 페이지 구성을 한 눈에 파악하기 용이
    한 페이지의 컴포넌트를 적절한 컴포넌트로 분리하여 구성하면 해당 컴포넌트의 구조를 파악하기 용이.

컴포넌트의 종류

컴포넌트를 선언하는 방식에는 Class Component와 Function Component가 있음.

  1. 클래스 컴포넌트
// App.js
import React from 'react';

class App extends React.Component {
  render() {
    return <h1>This is Class Component!</h1>;
  }
}

export default App;

클래스 컴포넌트는 render() 메서드가 있어야 하고 그 내부에 화면에 보여줄 JSX(JS Syntax eXtension)을 반환함. state 및 lifecycle API를 통해 관련 기능을 사용할 수 있음.

  1. 함수 컴포넌트
// App.js

import React from 'react';

const App = () => {
  return <h1>This is Function Component!</h1>;
};

export default App;

함수 컴포넌트는 render()메서드 없이 JSX를 반환하는 방식
훨씬 간단 but state와 lifecycle을 관리하지 못함.
하지만 React 16.8ver부터 Hook 기능이 추가되어 함수 컴포에도 state가 사용 가능해졌고 이 때부터 함수 컴포넌트가 더 많이 사용되기 시작함.

컴포넌트의 사용

리액트는 소문자로 시작하는 요소는 HTML로 인식하기 때문에 컴포넌트 명은 항상 첫 글자가 대문자가 되어야 함.

html 태그 컴포넌트

선언한 컴포넌트는 다른 곳에서도 import해서 사용 가능

예시)

// src/pages/Curriculum/Curriculum.js

import GNB from '../components/GNB/GNB';
import LNB from './LNB/LNB';
import Session from './Session/Session';

const Curriculum = () => {
  return (
    <>
      <GNB />
      <div className="curriculum">
        <LNB />
        <Session />
      </div>
    </>
  );
};

export default Curriculum;

----------------------------------
// src/pages/Curriculum/Session/Session.js

import SessionTitle from './SessionTitle/SessionTitle';
import SessionContent from './SessionContent/SessionContent';

const Session = () => {
  return (
    <>
      <SessionTitle />
      <SessionContent />
    </>
  );
};

export default Session;

JSX

JSX 정의

JSX란 리액트에서 사용하는 JS 확장 문법
바닐라 JS는 html에서 마크업된 부분들을 확인하면서 직접 해당 DOM에 접근하고 Event Listener를 부착하는 등 HTML과 JS는 서로 긴밀하게 연결되어 있음.

하지만 JSX는 HTML과 자바스크립트 로직을 하나의 JS파일 안에서 모두 처리하기 위해 확장한 문법!

JSX로 작성한 코드는 브라우저에서 동작하기 전에 Babel이라는 transcompiler를 통해 일반 JS 코드 형태로 변환됨.

JSX의 특징

JSX는 HTML 태그와 유사함.

JSX 문법

  1. JSX element
    JSX 문법을 통해 자바스크립트 파일 어디에서나 필요한 곳에 HTML처럼 작성 가능.

const hi = <p>Hi</p>;
이렇게 변수에 할당하거나 함수의 인자로 넘길 수도 있음.

  1. JS 표현식
    JSX 내부에서 JS 값을 출력하고 싶으면 {...JavaScript...}와 같이 {} 안에 유효한 자바스크립트 표현식을 작성 가능함.
// Greetings.js
import React from 'react';

const Greetings = () => {
  const name = '김개발';

  return <h1>{name}, Welcome to Wecode!</h1>;
};

export default Greetings;
  1. JSX attribute
    태그의 속성명은 camelCase로 작성해야 함. 속성을 추가하고 싶을 때는 실제 HTML에서 쓰는 속성명과 다를 수 있으니 React 공식문서를 참고해라.
    class -> className
    tabindex -> tabIndex
/* HTML
<h1 class="greetings">Welcome to Wecode!</h1>

/* JSX
<h1 className="greetings">Welcome to Wecode!</h1>
  1. Event 처리
    JSX는 태그를 작성할 때 직접 이벤트와 이벤트 핸들러를 부여 가능
  • 이벤트 앞에는 ondㅡㄹ 붙여 camelCase 작성
  • 문자열이 아닌 함수로 이벤트 핸들러 전달
// JS
const title = document.getElementsByClassName("title")[0];
title.addEventListener("click", handleClick);

// JSX
<h1 className="title" onClick={handleClick}>
  Welcome to Wecode!
</h1>
  1. inline styling
// HTML
<h1 style="color:red;background-image:yellow">Welcome to Wecode!</h1>

// JSX
<h1 style={{ color: "red", backgroundImage: "yellow" }}>
  Welcome to Wecode!
</h1>

바깥 중괄호는 JSX문법 안의 중괄호는 JS 객체 의미.

주의 : inliine styling은 css보다 성능이 낮고 우선순위가 높아 동적으로 계산하여 스타일링하는 경우 외에는 사용을 지양하라.

  1. Self-Closing Tag
    어떤 태그라도 셀프 클로징 태그로 사용 가능
    img도 <img /> 이렇게 끝내줘야 하고
    <div />은 <div></div>와 같은 표현이다.
// Bad
const Greetings = () => {
  return (
    <h1>김개발님!</h1>
    <h2>위코드에 오신 걸 환영합니다!</h2>
  );
}

// Good
const Greetings = () => {
  return (
    <div>
      <h1>김개발님!</h1>
      <h2>위코드에 오신 걸 환영합니다!</h2>
    </div>
  );
}
  1. Nested JSX
// Bad
const Greetings = () => {
  return (
    <h1>김개발님!</h1>
    <h2>위코드에 오신 걸 환영합니다!</h2>
  );
}

// Good
const Greetings = () => {
  return (
    <div>
      <h1>김개발님!</h1>
      <h2>위코드에 오신 걸 환영합니다!</h2>
    </div>
  );
}

JSX를 하나의 태그로 감싸야 하는 이유는, 리액트의 Virtual DOM에서 컴포넌트 변화를 효율적으로 비교할 수 있도록 한 컴포넌트는 하나의 DOM 트리 구조로 이루어져야 한다는 규칙이 있기 때문입니다)

  1. React.Fragment
    앞서 JSX에서는 반드시 최상위를 하나의 태그로 감싸야 한다고 했습니다. 그런데 최상위를 감싸고 있는 태그에 특별한 의미나 스타일이 없다면 불필요한 요소를 생성하게 됩니다. 이 때 유용하게 사용되는 것이 <React.Fragment>입니다. Fragment는 추가적인 DOM element를 생성하지 않고 하나의 컴포넌트 안에 여러 요소(자식)를 간단하게 그룹화할 수 있는 기능입니다.
const Greetings = () => {
  return (
    <React.Fragment>
      <h1>김개발님!</h1>
      <h2>위코드에 오신 걸 환영합니다!</h2>
    </React.Fragment>
  );
};
----------축약문법--------------------
const Greetings = () => {
  return (
    <>
      <h1>김개발님!</h1>
      <h2>위코드에 오신 걸 환영합니다!</h2>
    </>
  );
};

Node.js & npm

리액트 프로젝트를 시작하기 위해서는 Node.js를 설치해야 한다.

Node.js

자바스크립트는 웹 브라우저에서 동작하기 위한 언어로 탄생했고 그렇기 때문에 자바스크립트의 실행환경인 각 브라우저마다 자바스크립트를 해석할 수 있는 엔진이 있고 크롬의 엔진은 "V8"이다.

웹 밖에서도 자바스크립트를 이용해 개발을 하고자 하는 수요가 증가하면서 탄생한 것이 Node.js이다. Node.js로 인해서 브라우저 외의 어플리케이션을 제작하는데 다른 언어들을 쓰지않고 JS언어를 이용해서도 가능해진 것!!

리액트 어플은 웹 브라우저에서 실행되어 Node.js와 직접적 연관은 없다 하지만 리액트 외에 프로젝트를 개발하는데 필요한 주요 도구들(e.g.Babel, Webpack 등)은 웹 브라우저가 아닌 우리의 작업 환경에서 동작해야 하기 때문에 반드시 Node.js가 필요하다.

node.js는 크롬 V8 JavaScript 엔진으로 빌드된 JavaScript 런타임
런타임 === 실행환경(특정 프로그램을 실행하기 위한 환경)

예) 메모장 : txt파일을 위한 실행환경

npm

Node.js를 설치하면 Node.js 환경에서 사용 가능한 패키지들을 관리할 수 있는 도구인 npm(node package manager)도 함께 설치된다.

  • 패키지 : node에서 실행 가능한 프로그램들

    Node : IOS / npm : App store (비유) / Package : App

    $ npm install [패키지명]           // 패키지 다운로드
    $ npm update [패키지명]            // 패키지 업데이트
    $ npm uninstall [패키지명]         // 패키지 삭제
         ```

Node.js 설치하기

Node.js 홈페이지에 가서 LTS(Long term support) 버전을 설치하시오.
Home brew로 설치했다면 검색해서 LTS버전으로 바꾸길 권장!

  • 버전확인(터미널)
    node -v
     npm -v 
    Repl 모드로 node 실행하기
    $ node
    Welcome to Node.js v16.17.0.
    Type ".help" for more information.
    > console.log("Hello World")
    Hello World
    undefined
    
    종료 <cmd + c > or <.exit -> Enter(키입력)>

CRA

CRA?

리액트는 UI기능만 제공하여 웹 애플리케이션을 만들기 위한 개발환경을 직접 구축해야하는 경우가 많다. 직접 구축 시 성능 최적화에 유리하지만 유지보수에 신경 쓸 일이 많아서 처음에는 어려울 수 있다. 때문에 리액트 팀에서 프로젝트 시작을 위한 개발환경의 세팅을 도와주는 도구인 Create React App을 제작했다.

CRA를 통한 프로젝트 구축

1. 폴더진입

터미널에서 프로젝트를 시작하고자 하는 폴더에 진입
또는 vscode로 해당 폴더 열고 pwd 이용해 위치 확인.
cd [프로젝트 구축 폴더]

2. 프로젝트 설치

프로젝트를 시작하고자 하는 폴더에 위치하였는지 확인 후 리액트 프로젝트 설치(이름은 대문자나 특수문자는 에러의 위험으로 케밥 케이스 네이밍 지향)
npx create-react-app [프로젝트명]
npx : npm명령어 (create-react-app 패키지를 다운받지 않고 바로 실행하여 사용 가능함)

3. 프로젝트 폴더 진입

CRA를 통해 리액트 프로젝트를 설치하면 프로젝트 명으로 된 폴더가 생기고 여기에 진입하면 됨.
cd [프로젝트이름]

4. 로컬 서버 띄우기

웹 개발을 할 때는 서버가 필요하다. 웹 서버를 구축하지 않고 로컬에도 가상 서버를 구착할 수 있다.(로컬 서버)

npm start // 종료 ctrl + c

5. 로컬 서버 확인

npm start 명령어를 입력하면 아래 메시지와 https://localhost:3000 이라는 로컬 서버주소를 확인할 수 있음.

CRA 프로젝트가 잘 설치되었으면 해당 주소에 접근하면 아래와 같은 화면을 확인할 수 있음. 이후 코드를 수정할 때마다 변경되는 UI를 확인하며 개발을 진행할 수 있음.

실습해보기

폴더 진입(cd 폴더) -> pwd로 위치 확인 -> npx create-react-app 프로젝트명
결과 이미지

->npm start
터미널에 위와 같은 화면이 출력 & 브라우저에는 react아이콘이 빙글빙글 돌아가는 화면이 출력됨.(서버를 종료하려면 ctrl + c


CRA 초기 세팅

cra 초기 폴더 및 파일 구성

CRA를 통해 프로젝트를 설치하면 데모를 위한 기본 파일이 존재.
Publc 폴더의 index.html, src 폴더의 index.js, package.json 외의 파일은 데모를 위한 파일로 삭제가 가능하며 이외의 폴더와 파일은 프로젝트 기획에 맞게 새롭게 구성 가능하다.

node_modules, .gitignore, package.json

node_module

npm으로 다운 받은 패키지들의 소스코드들이 담긴 폴더.
추가적으로 설치된 패키지들은 node_moduels의 하위 폴더로 생성됨.

.gitignore(cra 프로젝트를 생성하면 자동으로 git init이 됨)

이 파일은 용량, 보안 등 여러가지 문제로 GitHub에 올리지 않을 파일들을 추가 가능함.

package.json

CRA 기본 패키지 외에 추가로 설치된 라이브러리 혹은 패키지의 종류, 버전 등의 정보가 기록되는 파일.
npm으로 설치 시 package.json의 dependecies에 라이브러리나 패키지의 정보가 자동으로 추가됨.

  1. dependencies
    npm을 통해서 설치한 모든 패키지 리스트와 버전 확인이 가능. 관련된 패키지의 실제 코드는 node.modules폴더에 존재

  2. scripts
    리액트 프로젝트를 실행하기 위해서 사용할 수 있는 명령어 관리.
    예) 로컬서버 시작 : npm start
    배포모드 실행(프로젝트 폴더 안에 배포를 위한 파일 생성) : npm build

  3. package-lock.json
    npm을 사용해서 패키지를 설치하거나 업데이트하면 자동으로 생성되거나 수정되는 파일(설치된 패키지의 정확한 버전이 명시되어 있음)

    패키지를 node_modules와 package.json에서 이중으로 관리 하는 이유?

    프로젝트 진행은 Git과 Github를 통해 협업으로 진행, 관리하기 때문에 CRA를 통해서 프로젝트를 설치하게 되면 node_modules는 많은 용량의 패키지로 구성되게 된다. 이를 Git에서 추적하지 않게 하고 package.json에 정보만을 기록해두면 팀원이 npm install이라는 명령어만으로 똑같은 버전의 패키지들을 설치할 수 있게 된다.

    깃에서 다운받으면 node_modules 파일은 .gitignore에 등록되어 있기 때문에 없는 채로 받지만 package.json의 dependancies에 설치된 패키지들의 정보가 있으니 npm install 명령어만으로 필요 패키지를 받을 수 있다.
    (결과 : 해당 프로젝트 폴더에 node_modules 파일이 생성된다)

    index.html, index.js, App.js

    public/index.html

리액트는 SPA(single page app)로 하나의 index.html이 존재하며 웹 브라우저에 보여지는 파일이다. 리액트는 index.html을 직접 수정하지 않고 index.js를 통해 index.html의 id가 root인 div 내부에 코드를 추가하여 화면을 구성하게 함.


퍼블릭 폴더의 역할
우리가 웹을 배포한다는 건 특정 폴더를 서버 컴퓨터에 올려두는 것입니다. 그래서 서버와 연결된 특정 URL로 접근하면 해당 폴더의 파일을 요청할 수 있고, 뒤에 따로 추가적인 URL을 붙이지 않으면 index.html을 요청한다는 의미가 됩니다. 예를 들어, https://naver.com 로 접근하면 naver.com에 연결되어있는 서버 컴퓨터의 폴더에 접근해서 index.html을 가져오는 것입니다. CRA를 배포했을 때 실제 서버에 배포되는 폴더가 public 폴더입니다. 우리 서버 주소로 접근하면(개발 서버의 경우는 http://localhost:3000) public 폴더에 들어가는 것과 같다고 생각하시면 됩니다. 그래서 우리가 public에 특정 디렉토리, 파일을 만들어두면 서버 URL을 통해서 접근이 가능한 것입니다.

예를 들어, public/images/logo.jpg 파일을 만들어두면, 서버에 접속해서 해당 파일에 접근할 수 있습니다. 실제로 http://localhost:3000/images/logo.jpg 를 브라우저 주소창에 입력하면 브라우저상에서 해당 이미지를 볼 수 있습니다.


src/index.js

리액트의 시작이 되는 파일.
react 컴포넌트와 html페이지를 연결하는 역할.

import React from "react";
import ReactDOM from "react-dom/client";
import App from "./App";

const root = ReactDOM.createRoot(document.getElementById("root")); // 1
root.render(<App />); // 2
           
  1. index.js에서는 document.getElementById로 index.html안에 id가 root인 요소에 접근
  2. html요소 또는 리액트 요소 등의 코드가 눈으로 볼 수 있도록 그려지는 것을 렌더링이라고 하며 index.js에서 render()안에 컴포넌트가 렌더링 된다.

※ src 폴더? : 개발에 사용되는 소스 파일을 모아두는 폴더

App.js

CRA 설치 후, 웹 어플리케이션의 첫 화면에 그려지고 있는 파일이며 데모를 위한 초기 컴포넌트

요약정리
1. CRA는 SPA다
2. 유일한 HTML은 public/index.html
3. 이 안에는 id가 root인 div tag하나만 존재 함.
4. 리액트는 html이 아닌 JS를 이용해서 만든 컴포넌트로 UI를 구성
5.CRA에서 최초로 만들어져 있는 데모용 컴포넌트가 App.js
6. index.html과 component의 중간다리는 index.js

README.md

프로젝트에 대한 정보를 나타내기 위해 작성하는 파일로 프로젝트의 지침서.
마크 다운 형식을 작성하고 고정된 양식은 없다. 리드미를 작성함으로써 어떤 프로젝트인지 알기 쉽고, 어떻게 사용하는지 여러가지 메타 정보를 문서화하여 사용자에게 정보를 제공 가능하다.

README.md 예시

Q&A

npm start - local serval 띄우기
npm test - 여러 테스트를 수행하기 위한
npm build - 실제 배포하기 위해 정적 파일로 변환

리액트로 css 옮기니 클라스가 겹쳐서 깨짐 ;;
나도 body 없애버림. 사스와 라우터가 해결해두륌~

profile
주먹구구식은 버리고 Why & How를 고민하며 프로그래밍 하는 개발자가 되자!

0개의 댓글