리액트 입문 - ES6문법과 Yarn과 리액트 시작

새벽로즈·2023년 10월 31일
1

TIL

목록 보기
35/72
post-thumbnail

리액트

  • 공식문서에서는 A JavaScript library for building user interfaces"로 소개됨.
  • UI를 구축하는 데 사용되며, 이는 웹 또는 앱의 프론트 엔드 부분을 의미.
  • SPA 기반의 프론트엔드 개발 프레임워크
  • 컴포넌트 단위의 독립적인 블럭을 활용한 개발
  • 유사한 프레임 워크는 Vue, Angluar가 있음

SPA

  • Single Page Application 아키텍쳐
  • 한개의 페이지로 이루어진 애플리케이션임
  • MPA(Multi Page Application)과 상반된 개념
  • 서버에 1회 리소스를 요청함
  • 그 이후에는 필요한 경우에만 데이터를 받아와서 기존 페이지를 수정하는 방식으로 화면을 수정함
  • 자연스러운 UX(사용자 경험)이 가능함

SPA의 단점 : SEO에 약하다

SEO(Search Engine Organization)는 전통적인 HTML 구조가 아니어서 SEO(Search Engine Optimization)에 어려움을 겪음. 이로 인해 검색 엔진 로봇은 SPA 페이지를 찾기 어렵고, 페이지의 전체 콘텐츠를 이해하기 어려워진다. SPA를 사용하는 경우, SEO를 고려하고 검색 엔진이 페이지 콘텐츠를 인식할 수 있도록 추가적인 작업이 필요함.

SPA 프레임워크 종류

1) ReactJS
페이스북 개발, 강력한 커뮤니티.
2) VueJS
간결하고 쉬운 학습.
꾸준한 성장, 상대적으로 낮은 점유율.
3) AngularJS
안정성과 강력함.
학습 어려워 낮은 시장 점유율.

컴포넌트

리액트가 채택한 개발방법
컴포넌트는 벽돌이다라고 생각하기
Header 컴포넌트, Body컴포넌트, Footer컴포넌트

렌더링

변경사항만 바꿔주는 것을 렌더링이라고 함


ES6 : 상수와 변수

과거에는 변수를 선언할 때 모두 var 키워드를 사용했음.
그러나 현재는 const와 let이 등장하여 변수 선언 방식이 진화됨.
let (변수):
재할당이 가능

const (상수):
재할당이 불가능
내부 속성값은 수정 가능

☞ 둘 다 block level scope를 가지고 있어서 블록({}) 내에서 선언된 변수는 해당 블록 내에서만 유효함

ES6 : var를 쓰면 안되는 이유

if (1 == 1) {
  var a = 3;
  // const a = 3;
}

console.log(a); //여기서도 3이 출력 되기 때문

ES6 : 자바스크립트에서 말하는 object(오브젝트)

  • key, value, pair로 구성됨
  • 함수도 넣을수 있음
const person = {
  name : 'nana',
  age : 30,
  toDoList : function(){} // 혹은 () => 
}
  • 생략도 가능
const name = 'nana'; 
const person = {
  name,
  age : 30,
  toDoList : function(){} // 혹은 () => 
}

ES6 : 얕은 복사

const 객체1 = {1: 10 };

// 얕은 복사
const 객체2 = 객체1;
객체1.1 += 1; 

console.log('객체1:', 객체1); // 결과 : 객체1: { 값1: 11 }
console.log('객체2:', 객체2); // 결과 : 객체2: { 값1: 11 }
  • 객체2 = 객체1; 하는 부분이 얕은 복사임
  • 얕은 복사는 변수에 객체를 할당할 때, 참조(주소값)를 복사하는 방식임
  • 따라서 객체1과 객체2는 동일한 메모리 위치를 참조하게 됨.
  • 만약 객체2를 통해 내부 값을 변경하면, 객체1도 영향을 받음

※ 참조 : 변수나 값이 메모리 상의 어떤 위치를 가리키는 것을 의미

ES6 : 깊은 복사

// 깊은 복사
const 객체3 = JSON.parse(JSON.stringify(객체1));
객체1.1 += 1;
console.log(`객체3:`, 객체3);  // 결과 : 객체3: { 값1: 10 }
  • 깊은 복사는 객체를 완전히 복제하여 새로운 메모리 공간에 저장하는 방식임
  • JSON.stringify를 통해 객체를 문자열로 변환하고, 다시 JSON.parse를 통해 객체로 변환함으로써 새로운 메모리에 복사함
  • 객체1을 변경하더라도 객체의 구조를 변경하지 않아서 객체3은 영향을 받지 않음

ES6 : Template Literals

const Age = "20";
console.log(`저는 ${Age}입니다.`);
  • 템플릿 리터럴은 문자열 표현을 간편하게 만들어주는 ES6의 기능으로, `(백틱)을 사용함
  • ${}을 사용해서 변수를 넣을 수 있음
  • 멀티라인을 지원함 (줄바꿈 가능)

ES6 : 객체의 구조분해할당

   const person = {
     name: '나나',
     age: '20'
   };

   const { name, age } = person; // 구조분해할당 
   console.log(`${name}님, ${age}살이시네요!`);

☞ 구조분해할당은 'name' 변수에는 'person' 객체의 'name' 속성 값이, 'age' 변수에는 'person' 객체의 'age' 속성 값이 할당됨

  • 구조분해할당의 장점
    1) 객체의 속성을 여러 변수에 할당하지 않고 한줄로 가능해서 코드가 간결해지기 때문에 가독성이 향상됨
    2) 객체의 속성과 변수의 이름을 일치해서 const { name, age } = person; 이런식으로 직관적으로 가능함
    3) 동일한 객체의 속성을 여러번 사용해야할 때 반복적으로 쓰지 않아도 되어서 좋음
    4) 변수 할당을 한줄로 처리하기 때문에 코드 작성과 유지보수가 용이함
    5) 함수의 매개변수로 객체를 전달하고 함수 내에서 구조분해할당을 하게 되면 손쉽게 객체의 속성을 사용 할 수 있음
const person = {
  name: '나나',
  age: '20'
}

// 함수 정의 시 객체를 매개변수로 받고, 내부에서 비구조화 할당
function hello({ name, age }) {
  console.log(`${name}님, ${age}살이시네요!`);
}

// 함수 호출 시 객체를 전달
hello(person);

ES6 : 배열의 구조분해할당

배열에서도 객체의 구조분해할당처럼 가능함

const number = [5, 10, 15, 17, 21];
const [one, two, three, four, five, six] = number;
console.log("one", one); // one 5
console.log("two", two); // two 10
console.log("three", three); // three 15
console.log("four", four); // four 17
console.log("five", five); // five 21
console.log("six", five); // six underfined

ES6 : 전개 연산자

  • ...을 의미함

  • 배열이나 객체의 요소를 분해하거나 합칠 때 사용함

let [name, ...rest] = ["Nana", 20, "Seoul"];
  • 'name': 배열의 첫 번째 요소인 'Tom'을 'name' 변수에 할당함
  • '...rest': 나머지 요소를 'rest'라는 배열에 할당함
console.log(name);  // 출력: 'Nana'
console.log(rest);  // 출력: [20, 'Seoul']

ES6 : 전개 연산자 왜 필요한지?

왜 이게 필요한가 싶었다. 사실 자바스크립트문법반 강의는 이해가 잘 안되었었는데, 다급하지않고 여유로운 마음을 좀 가지니 이해력이 많이 상승하는 것 같다.

let names = ["Steve", "John"];
let students = ["Tom", names];
console.log(students);

☞ 출력값이 ['Tom', 'Steve', 'John' ]이 아닌 [ 'Tom', [ 'Steve', 'John' ] ]이 나와서 원하는 대로 ['Tom', 'Steve', 'John' ] 만들기 위해서 필요함

[해결방안]

let names = ["Steve", "John"];
let students = ["Tom", names];
console.log(students);

☞ ...을 사용하면 해결 됨


ES6 : 얕은복사를 이용한 전개연산자

let tom = {
  name: "Tom",
  age: 10,
  region: "Seoul",
};

let steve = {
  ...tom,
  name: "Steve",
};
console.log(tom);
console.log(steve);

☞ tom의 정보를 복사하고 name을 steve로 바꿨음

ES6 : 화살표 함수

function 함수1(x, y) {
  return x + y;
}

const 함수2 = (x) => x + 3;
const 함수3 = (x, y) => {
  return x + y;
};

console.log(함수1(1, 2));
console.log(함수2(1));
console.log(함수3(1, 2));

☞ function(){} 대신 () => {}로 줄여 쓸수 있음


리액트 개발환경 세팅

  1. 크롬 브라우저 설치
    https://www.google.co.kr/chrome

  2. 코드편집기 VS CODE 설치
    https://code.visualstudio.com

  3. Git 설치
    https://git-scm.com/downloads

  4. Node 설치
    https://nodejs.org/en/download

리액트 개발환경 세팅(2) - Yarn

  1. Yarn 설치
npm install -g yarn

☞ -g는 global을 의미함 → 내 컴퓨터 내에서 사용하겠다는 뜻

  1. Yarn 설치 되었는지 확인하기
yarn -v

☞ 1.22.19 이런식으로 현재 버전이 출력됨

  1. Yarn으로 패키지 설치하기
yarn add 패키지이름

☞ npm의 경우 npm install 패키지이름 으로 설치함


NPM? Yarn?

  1. NPM 과 Yarn의 공통점
    자바스크립트 런타임 환경인 Node.js의 패키지 관리자로 온라인 데이터베이스에서 패키지를 쉽게 관리.

  2. NPM 과 Yarn의 차이점
    1) npm
    Node.js 설치 시 자동 생성.
    Node Package Manager의 약자.
    npm 플랫폼 자체.

2) yarn
2016년 페이스북에서 개발.
npm과 호환성 우수, 속도와 안정성에서 월등히 좋음.
속도: Yarn 우세.
보안: Yarn 우세 (최근 npm의 보안 업데이트가 크게 향상됨).

런타임

프로그래밍 언어가 구동되는 환경을 말함
1) 브라우저 환경

  • 웹 브라우저 상 개발자도구에서 콘솔 사용을 할 수 있음
  • alert 같은 브라우저상에서만 사용 가능한 것들이 있음
    2) 노드 환경
    node 파일명.js 처럼 실행할 수 있음

☞ 리액트는 브라우저 환경에서 개발을 진행함


리액트 CRA

  • CRA는 Create React App을 의미함.
  • 한 줄의 명령어 입력으로 React 프로젝트 개발에 필수요소를 자동으로 구성하는 방법

Yarn CRA 해보기

yarn create react-app 프로젝트이름

☞ 파워쉘에 입력하면 알아서 설치해준다 (짱신기)

Yarn 구동하기

cd 프로젝트이름
yarn start

☞ 해당 폴더로 이동해서 yarn start라고 입력하면 구동이 된다.

코드 입력해보기

  • Src 폴더 안의 App.js 파일의 코드에 코드를 수정하면 새로고침 할 필요없이 즉시 적용이 된다.

  • 라이브 서버 없이 되는 것이 신기했음!

  • public폴더의 index.html에는 root라는 id를 가진 div 박스가 하나 존재하는데 이걸 index.js에서 리액트 관련으로 렌더링 해준다. 사실상 결론은 코드를 작성할만한 곳은 App.js라고 보면 된다.

☞ 결론 : App.js에서 코드수정을 하는 것이 리액트 개발인 것!

Src 폴더를 절대 경로로 만들기

1) jsconfig.js 파일을 root에 만들기
2) 아래 코드 입력

{
	"compilerOptions": {
		"baseUrl": "src"
	},
	"include": ["src"]
}

☞ 장점 : Src에 있는 모든 파일들의 경로를 절대경로로 설정하면 번거롭게 ./././이 필요없음

그렇다면, import "./App.css"; 말고 import "App.css";이 가능해진다는 소리임


리액트 컴포넌트

  • 컴포넌트는 함수형과 클래스형이 있는데 함수형을 주로 쓰게됨

  • 컴포넌트는 내보내기 들여오기가 가능함

  • 컴포넌트 내부에는 JS를 쓸 수 있는 공간이 있다.

  • 컴포넌트의 이름의 시작은 대문자여야함. (소문자는 오류남)

  • Return에는 html이 아닌 JSX(JS + XML)문법을 사용함

  • Return에 JS를 쓰고 싶다면 {}로 사용함

1) 버튼에 함수를 사용할 수 있음

import React from "react";
function App() {
  // <---- 자바스크립트 영역 ---->
  return (
    /* <---- HTML/JSX 영역  ---->*/
    <div
      style={{
        height: "100vh",
        display: " flex",
        flexDirection: "column",
        justifyContent: "center",
        alignItems: "center",
      }}
    >
      {/* 이곳에 퀴즈를 위한 html 코드를 작성해 주세요 */}
      <p>이것은 내가 만든 APP 컴포넌트입니다.</p>
      <button
        onClick={function () {
          alert("클릭!");
        }}
      >
        클릭!
      </button>
    </div>
  );
}

export default App;

2) 변수화 시켜서도 가능함

import React from "react";
function App() {
  // <---- 자바스크립트 영역 ---->
  function onClickButtonHandler() {
    alert("클릭");
  }
  return (
    /* <---- HTML/JSX 영역  ---->*/
    <div
      style={{
        height: "100vh",
        display: " flex",
        flexDirection: "column",
        justifyContent: "center",
        alignItems: "center",
      }}
    >
      {/* 이곳에 퀴즈를 위한 html 코드를 작성해 주세요 */}
      <p>이것은 내가 만든 APP 컴포넌트입니다.</p>
      <button onClick={onClickButtonHandler}>클릭!</button>
    </div>
  );
}

export default App;

☞ html과 다르게 {}를 사용함


부모 컴포넌트와 자식 컴포넌트

부모 컴포넌트 : 다른 컴포넌트를 품는 컴포넌트
자식 컴포넌트 : 다른 컴포넌트 안에서 품어지는 컴포넌트

//자식 컴포넌트
function Child() {
  return <div>나는 자식입니다.</div>;
}
//부모 컴포넌트
function App() {
  return <Child />;
}

☞ function Child() 이렇게 분리하는 것이 '컴포넌트화'

멀티라인은 부모요소가 필요함

function Child() {
  return <div>나는 자녀입니다.</div>;
}
function App() {
  return (
    <div>나는 자녀입니다.</div>
    <div>나는 자녀입니다.</div>
    <div>나는 자녀입니다.</div>
    <div>나는 자녀입니다.</div>
  )

☞ 이렇게 하면 JSX 식에는 부모요소가 하나 있어야 한다고 함

  1. 해결방법 - 부모 div 만들어주기
function Child() {
  return <div>나는 자녀입니다.</div>;
}
function App() {
  return (
    <div>
      <div>나는 자녀입니다.</div>
      <div>나는 자녀입니다.</div>
      <div>나는 자녀입니다.</div>
      <div>나는 자녀입니다.</div>
    </div>
  );

☞ 웹상에서 부모 div가 존재함

  1. 해결방법 - 부모 빈 태그 만들기
function Child() {
  return <div>나는 자녀입니다.</div>;
}
function App() {
  return (
    <>
      <div>나는 자녀입니다.</div>
      <div>나는 자녀입니다.</div>
      <div>나는 자녀입니다.</div>
      <div>나는 자녀입니다.</div>
    </>
  );

☞ 웹상에서 자식 div 들만 출력 됨

  1. 컴포넌트화로도 가능함
function Child() {
  return <div>나는 자녀입니다.</div>;
}
function App() {
  return (
    <div>
      <Child />
      <Child />
      <Child />
      <Child />
    </div>
  );

컴포넌트를 부모-자식 관계로 연결도 가능

function Child() {
  return <div>나는 자녀입니다.</div>;
}

function Mom() {
  return <Child />;
}

function GrandMom() {
  return <Mom />;
}
function App() {
  return <GrandMom />;

☞ 최종적으로 나는 자녀입니다가 출력됨

jsx

리액트에서는 딱 하나의 html만 존재함 (public/index.html)
그럼 리액트에서 어떻게 뷰를 그릴까요? App.js 파일에서 보이듯,
JSX 문법을 사용해서 React 요소를 만들고 DOM에 렌더링 시켜서 그림

리액트 스니펫이 있음

vs code 익스텐션에서 'react snippet'이라고 검색 후 설치

사용법
rfc 혹은 rfec 입력하면 아래와 같은 기본 폼 나옴

import React from 'react'

export default function App() {
  return (
    <div>App</div>
  )
}

JSX 실습해보기

1) 태그는 꼭 닫아주기
2) 최상위 태그 하나만 있어야함
3) 아래 코드처럼 삼항연산자 쓸수 있음

import React from "react";

export default function App() {
  const number = 1;
  return (
    <div>
      <p>안녕하세요</p>
      {/* 이것은 주석 */}
      <p>
        {number > 10 ? number + "은 10보다 크다" : number + "은 10보다 작다"}
      </p>
    </div>
  );
}

4) Class 대신 ClassName

<div className="App">

☞ 이렇게 사용해야 적용이 됨

5) 스타일은 html과 약간 다르게 사용됨

//1번째 방법
<p style={{color: 'orange', fontSize: '20px'}}>orange</p>

//2번째 방법
function App() {
  const styles = {
    color: 'orange',
    fontSize: '20px'
  };

  return (
    <div className="App">
      <p style={styles}>orange</p>
    </div>
  );
}

오늘의 한줄평 : 어려웠던 심화 부분을 이해해서 좋았고, 리액트로 만드는건 신기하다!!!

profile
귀여운 걸 좋아하고 흥미가 있으면 불타오릅니다💙 최근엔 코딩이 흥미가 많아요🥰

0개의 댓글