본문 바로가기

React/소플 React 강의

[2022.07.28]React- 소플 강의 정리

소플의 처음 만난 리액트 -초청 강의 수강

 

react_sople>react01파일 참고)

 

HTML

웹사이트의 뼈대를 구성하기 위해 사용하는 마크업 언어

 

Tag: 태그를 사용해 뼈대를 만듦
기본 뼈대 태그: html, head, body


*
Single Page Application

 

한개의 페이지/ 각각 페이지를 만들면 효율적이지 않기에 한개 html파일 안에 body태그 안에 들어가는 content만 바꿔서 보여줌 =>SPA 리액트의 특징


JavaScript 

 

JavaScript : ECMAScript가 정식명칭, 그래서 ES6이런식으로 표준나타내는 용어쓰이는 것(2015년에 나옴,ES2015나 ECMAScript2015라고도 불림), ES12도나옴(2021년)
/ 생명을 불어넣는 역할, 스크립트 언어의 한 종류
C언어, 자바, C++등이 있는데 자바스크립트는 성격이 조금 다름. 프로그램이 실행되는 런타임에 실행이 된다.
컴파일언어: 소스를 짜면 컴퓨터가 이해할 수 있게 바꿔주는거, 컴파일이 보통 다른 언어인데 자바스크립트는 런타임에 실행 되는 것이 차이.
최근 몇년전은 파이썬이 많이 사용되었지만 요즘은 자바스크립트 사용범위가 넓어져서 많이 사용되고 있다. 

*
JavaScrip자료형(Data Type):
정수, array이런것을 자료형이라 함, 모든 변수는 하나의 자료형을 갖게 되는데, 자바는 변수를 선언하기 전 해당 변수의 자료형이 결정이 된다. 
자바스크립트는 let 변수명 하고 변수의 데이터가 대입되는 시점에 자료형이 결정 동적타이핑(타입이 결정되는 시점이 동적이다.)
var let중 요즘은 let을 선호, 
Number Type:
let n1=1234;


자바스크립트 Type


-String Type (문자열):
let s1="hello";
let s1='world';
큰따옴표, 작은따옴표 둘다 상관 없이 사용가능하지만 열고 닫는 건 set

-Boolean Type
let b1=true;
let b2=false;

-Null Type
let n=null;

-Undefind Type(값이 정의가 되지 않은 것)
let u1; (변수에 값이 대입되지 않아 언디파인드상태)
let u2=undefined; (언디파인드를 대입한 상태)

*null은 값이 정의가 되었는데 값이 null이란 뜻. Undefind Type(값이 정의가 되지 않은 것)이라 둘은 차이가 있다.

-Array Type (배열을 나타내는 자료형, 순서대로 늘어놓은 것, 변수를 순서대로 모아놨다는 것이 중요-각각의 변수에 번호index(0부터시작)가 붙음 /숫자, 문자 등 다양한 자료형이 배열안에 들어갈 수 있다. 배열안에 배열인 2차원..3차원도 가능)
let arr=[1,2,3,4];

-Object Type 
let obj={a:"apple",b:"banana"};

 



<배열 종류>


-Number타입으로만 이루어진 배열
let arr1=[1,2,3,4];

-string타입으로만 이루어진 배열
let arr2=["h","e"];

-Number타입과 String타입을 함께 사용한 배열
let arr3=[1,"h",2,"i"];

-다양한 자료형을 함께 사용한 배열 (잘 안씀)
let arr4=[true, 1, undifined, false, "h",2];

*다양한 객체 사용법
값으로 string 타입만을 사용한 객체
let obj1={a:"appple", b:"banana"};

-값으로 Number타입만을 사용한 객체
let obj2={a:1,b:2};

-값으로 다양한 자료형들을 함께 사용한 객체
let obj3={a:"hello",b:100, c:[1,2,3]};

-값으로 객체를 사용한 객체
let obj4={
 a:{a1:1,a2:2},
 b:{b1:3,b2:4},
};

console.log(obj3['c']);
console.log(obj4.b.b2);

 


 

<연산자>


*대입연산자
항상 오른쪽에서 왼쪽 방향으로 흐름이 흘러감 
let a=10;
let b=20;
console.log(a) //10출력

*사칙연산자 
 + - * / 


-나머지를 구하는 연산자 %


-지수연산자 **


-산술연산자
 ex.  a+=b //a=a+b와 같음


-증가연산자 ++
postfix방식: a++ 증감전에 값을 반환하고 이후 값이 바뀜
prefix방식:++a 값을 변환시키고 값을 반환한다.


-감소연산자 --


-관계연산자, 비교연산자 >, <, =, <=, >=

 

-동등 연산자

a==b  같다

a !=b 같지 않다

 

-일치 연산자

a===b 자료형과 값이 모두 같다

a!==b 값이나 자료형이 모두 같진 않다.

 

-이진 논리 연산자 :
a&&b : a와 b가 모두 true일 경우에만 true
a||b: a 또는 b가 true일 경우에는 true

 

-조건부 연산자 (삼항 연산자)



*타입스크립트언어: 모든 자바스크립트 언어 지원, 타입을 쓰는것. 규칙을 좀 더 엄격하게 한 언어

 


자바스크립트의 함수

 

파라미터, 인자

 

 

function sum(a,b){
 return a+b;
}

console.log(sum(10,20));

//출력 결과 :30

 

//arrow function expression을 사용

const multiply=

 

 


React

유저인터페이스를 만들기 위한 라이브러리

라이브러리: 자주 사용되는 기능들을 정리해서 모아 놓은 것

유저인터페이스: 사람(사용자)과 사물 또는 시스템, 기계, 컴퓨터 프로그램 등 사이에서 의사소통을 할 수 있도록 만들어진 물리적, 가상적 매개체

 

쉽고 빠르게 관리하기 위해 나타남  SPA 싱글페이지 애플리케이션

 

*사용

macOs=terminal

window=powerShell

 

*설치

1. node.js(javaScript runtime)

2. npm (node package manager) =>node.js를 설치하면 자동 설치 됨

 

node.js는 16버전 이상으로 설치

$node --version  을 터미널에 쳐서 정상 설치 확인

 

3. VS Code설치 (마이크로소프트, 무료이기 때문에 요즘 많이 사용)

IDE : vs코드같이 코드를 에디터할 수 있는 도구

 

 

사용자 인터페이스( user interface, UI)

UI 라이브러리

NGULAR JS(중단), react, vue.js, google 등

vue.js와 리액트가 사용빈도가 비슷했으나 요즘은 리액트를 많이 사용

 

 


<리액트 장점>

virtual DOM 버츄얼 돔 

- 리액트는 버츄얼돔을 사용한다.

 

버츄얼돔: 가상의 돔 , 실제 돔과 웹페이지 사이에서 중간 매개체 역할을 함

빠른 업데이트를 도움

 

-DOM: 웹페이지를 정의하는 하나의 객체

모든 웹사이트는 돔으로 되어 있다.

-사용자와 상호작용하는 웹페이지는 웹로딩,업데이트가 빠름

-화면이 바뀐다= 돔이 바뀐다

-돔을 직접 찾아 수정을 해야하는데 성능과 비용,시간에 영향을 많이 끼침,

=>리액트는 버츄얼돔을 만들어서 화면이 바뀔일이 생기면 빠르게 업데이트를 도와줌

 

-diff: 다른 부분 , compute Diff : 달라진 부분을 계산한다

 

 

component-Based

-리액트는 컴포넌트의 조합으로 이루어져 있다.

레고블록 조립하듯 컴포넌트들을 모아서 개발

 

-사이트 예시: 에어비앤비

 

재사용성

(개발할때 재사용성을 항상 생각하기)

 

-재사용성이 높아야 한다 = 해당 소프트웨어 도는 모듈이 다른 곳에서도 사용될 수 있도록 한다. 의존성을 낮추고 호환성을 높여 개발해야한다.

 

-컴포넌트가 다른 곳에서도 재사용될 수 있다. =>다른 곳에서도 사용될 수 있도록 컴포넌트 만들기

 

왜 재사용성을 고려하는가?

-개발 기간이 단축됨

-유지보수가 용이함 (모듈사이에 의존성이 낮기 때문에 어디서 버그가 났는지 쉽게 찾을 수 있다.)

 

META에서 지원을 해주기에 든든한 프로그램

 

활발한 지식공유&커뮤니티

깃허브

stackoverflow (개발자지식인같은 사이트)

react native (모바일앱 개발)

 


<리액트 단점>

방대한 학습량

계속 변동이 있음 

업데이트, 활발한 커뮤니티로 인한 변화, 트렌드 따라가야함

 

높은 상태관리 복잡도

-state :리액트 컴포넌트의 상태를 말함

-상태관리=state를 잘 관리 하는 것. (리덕스 등 외부상태관리프로그램을 사용)

-상태가 바뀜=state가 바뀜 / state가 바뀌면 랜더링을 다시 해야하기 때문에, 잘 관리 못하면 계속 랜더링 될 수 있음

 


 

* root Dom node 버츄얼돔의 시작, 뿌리

<body>
    <h1>블로그에 오신 여러분을 환영합니다</h1>
    <div id="root"></div>  =>root Dom
</body>

 


<버튼 만들기 예제>

react_sople>01파일 참고

+ 교재 p.83

index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>소플 강의 01</title>
    <link rel="stylesheet" href="styles.css">
</head>
<body>
    <h1>블로그에 오신 여러분을 환영합니다</h1>
    <div id="root"></div> <!-- root Dom Node -->

    <!-- 리액트 가져오기 /17기준은 책부분이라 한거고 요즘은 더 버전 업데이트 됨-->
    <script crossorigin src="https://unpkg.com/react@17/umd/react.development.js"></script>
    <script crossorigin src="https://unpkg.com/react-dom@17/umd/react-dom.development.js"></script>

    <!-- 리액트 컴포넌트 가져오기 -->
    <script src="MyButton.js"></script>
</body>
</html>

 

MyButton.js

function MyButton() {
  const [isClicked, setIsClicked] = React.useState(false);

  return React.createElement(
    "button",
    { onClick: () => setIsClicked(true) },
    isClicked ? "Clicked" : "Click here!"
  );
}

const domContainer = document.querySelector("#root");
ReactDOM.render(React.createElement(MyButton), domContainer);

 

▼ 버튼 클릭시 바뀌는 화면




 ▼ 변경된 버튼

 

참고:

https://ko.reactjs.org/docs/cdn-links.html

 

CDN 링크 – React

A JavaScript library for building user interfaces

ko.reactjs.org

 

 

 


리액트 설치

1. 설치하기 (터미널 아래에 쳐서 설치)

D:\file\react>npx create-react-app react01 

 

2.

 

+

creact next app 이란 것도 있으니 나중에 공부해도 좋음

 


JSX

Js =>JavaScript

JSX =>JavaScript+XML/HTML   /자바스크립트 문법을 확장시킨것

 

-자바스크립트 코드로 변환해준다.

React.createElement

 

-리액트에서 jsx를 쓰는 것이 필수는 아니지만 권장함

 

 


<JSX 장점>

간결한 코드

 

가독성 향상

-가독성 좋으면 버그발견이 쉽다.

 

Injection Attacks방어

 


 

 

 

 


<실습예제>

chapter_03파일

*교재 p.107 예제

Book.jsx

import React from 'react';

function Book(props) {
    return (
        <div>
            <h1>{`이 책의 이름은 ${props.name}입니다.`}</h1>
            <h2>{`이 책은 총 ${props.numOfPage}로 이뤄져 있습니다.`}</h2>
        </div>
    );
};

export default Book;

 

Library.jsx

import React from 'react';
import Book from './Book';

function Library(props){
    return (
        <div>
            <Book name="처음 만난 파이썬" numOfPage={300} />
            <Book name="처음 만난 AWS" numOfPage={400} />
            <Book name="처음 만난 리액트" numOfPage={500} />
        </div>
    );
};

export default Library;

 

index.js

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

import Library from "./chapter_03/Library";

const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(
  <React.StrictMode>
    <Library />
  </React.StrictMode>
);

// If you want to start measuring performance in your app, pass a function
// to log results (for example: reportWebVitals(console.log))
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
reportWebVitals();

 


리액트 Element

-Element :어떤 물체를 구성하는 성분 

Elements는 화면에서 보이는 것들을 기술

 

-리액트 Elements: 자바스크립트 객체 형태로 존재 / 리액트 앱을 구성하는 가장 작은 블록들

 

- 불변성을 갖고 있다= Elements 생성 후에는 Chidren이나 attributes를 바꿀 수 없다.

 

화면에 나타나는 내용을 기술하는 자바스크립트 객체

용어 descriptor > element로 변경됨

 

 

리액트 Component와 element  (교재 p.142)

컴포넌트로부터 엘리먼트가 만들어짐

컴포넌트는 어떠한 속성들을 입력으로 받아서 그에 맞는 리액트 엘리먼트를 생성하여 리턴해준다.

 

 

-리액트엘리먼트는 버츄얼돔에 있는것

-돔엘리먼트는 실제 돔에 존재 / 위와 차이가 있다.

 

-랜더링된 엘리먼트를 업데이트 하려면 다시 생성을 해야한다.

 

 


<시계만들기 실습 > (교재 p.132)

chapter_04파일

Clock.jsx

import React from 'react';

function Clock (props) {
    return (
        <div>
            <h1>안녕, 리액트!</h1>
            <h2>현재 시간: {new Date().toLocaleTimeString()}</h2>
        </div>
    );
};

export default Clock;

 

index.js

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

import Clock from "./chapter_04/Clock";

const root = ReactDOM.createRoot(document.getElementById("root"));

setInterval(() => {
  root.render(
    <React.StrictMode>
      <Clock />
    </React.StrictMode>
  );
}, 1000);

// If you want to start measuring performance in your app, pass a function
// to log results (for example: reportWebVitals(console.log))
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
reportWebVitals();

 

▼ 실행 화면


리액트는 Component-Based  컴포넌트 기반이다.

 

입력과 출력을 위해 Props를 사용한다.

Props: 컴포넌트에 전달한 다양한 정보를 담고 있는 자바스크립트 객체

컴포넌트라는 붕어빵틀에 props는 붕어빵 재료를 넣으면 element붕어빵이 나옴= 틀은 같지만 속성은 다름

props는 읽기만 가능=값을 변경할 수 없다.(붕어빵 다 구워졌으니 이미 나온 속재료를 바꿀수 없음)

 

에어비앤비 컴포넌트 예시

 

 

자바스크립트 함수의 속성

*pure함수 (입력값 변경 x)

function sum(a,b){

 return a+b;

}

 

*Impure함수: 입력값이 변경되는 함수

 

*모든 리액트 컴포넌트는 props를 직접 바꿀 수 없고, 같은 props에 대해서는 항상 같은 결과를 보여줄 것! (pure퓨어함수와 같은 역할을 해야 한다.)

 

아래 처럼 props사용

 

예시2 . 이렇게도 사용 가능

 


component 만들기

클래스보다 함수 컴포넌트를 요즘 사용함

함수컴포넌트 개선하기 위해 나온 것이  HOOK=> 함수컴포넌트+HOOK같이 사용

 

 

▼ 클래스 컴포넌트 예시

 

컴포넌트 이름은 항상 대문자로 시작해야 한다.

 

컴포넌트 속성을 다르게 사용 가능(컴포넌트 합성)

 

 

컴포넌트 추출

-추출한 컴포넌트를 재사용할 수 있게 하면 개발속도 향상, 유지보수 수월

-기능단위로 추출, 재사용 가능하게 추출하는 게 좋다!

 

 

▼ 위에서 Avatar컴포넌트 추출

 

 추출한걸 다시 넣어줌 (이렇게 사용하면 좀 더 가독성이 좋음)

 

UserInfo 컴포넌트도 만들시

 


작성방법 

스네이크 케이스(Snake Case)

snakae_case

 

 

카멜 케이스(Camel Case)

camelCase

 

 

케밥 케이스(Kebab Case)

kebab-case

 

 

파스칼 케이스(Pascal Case)

PascalCase

 

 


 

댓글 컴포넌트 만들기 예제 -교재 p.162

chapter_05파일

Comment.jsx

import React from 'react';

const styles = {
    wrapper: {
        margin: 8,
        padding: 8,
        display: "flex",
        flexDirection: "row",
        border: "1px solid grey",
        borderRadius: 16,
    },
    imageContainer: {},
    image: {
        width: 50,
        height: 50,
        borderRadius: 25,
    },
    contentContainer: {
        marginLeft: 8,
        display: "flex",
        flexDirection: "column",
        justifyContent: "center",
    },
    nameText: {
        color: "black",
        fontSize: 16,
        fontWeight: "bold",
    },
    commentText: {
        color: "black",
        fontSize: 16,
    },
};

function Comment(props) {
    return (
        <div style={styles.wrapper}>
            <div style={styles.imageContainer}>
                <img
                    src="https://upload.wikimedia.org/wikipedia/commons/8/89/Portrait_Placeholder.png"
                    style={styles.image}
                />
            </div>

            <div style={styles.contentContainer}>
                <span style={styles.nameText}>{props.name}</span>
                <span style={styles.commentText}>{props.comment}</span>
            </div>
        </div>
    );
}

export default Comment;

 

CommentList.jsx

import React from 'react';
import Comment from './Comment';

const comments = [
    {
        name: "이인제",
        comment: "안녕하세요, 소플입니다.",
    },
    {
        name: "유재석",
        comment: "리액트 재미있어요~!",
    },
    {
        name: "강민경",
        comment: "저도 리액트 배워보고 싶어요!!",
    },
];

function CommentList(props) {
    return (
        <div>
            {comments.map((comment) => {
                return (
                    <Comment name={comment.name} comment={comment.comment} />
                );
            })}
        </div>
    );
}

export default CommentList;

 

index.jsx

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

import CommentList from "./chapter_05/CommentList";

const root = ReactDOM.createRoot(document.getElementById("root"));

setInterval(() => {
  root.render(
    <React.StrictMode>
      <CommentList />
    </React.StrictMode>
  );
}, 1000);

// If you want to start measuring performance in your app, pass a function
// to log results (for example: reportWebVitals(console.log))
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
reportWebVitals();

 

▼ 실행화면


State

-리액트 컴포넌트의 상태, 리액트 컴포넌트의 변경가능한 데이터

-state는 개발잗가 직접 정의해서 사용한다.

-랜더링이나 데이터 흐름에 사용되는 값만 state에 포함시켜야 한다.

-state는 자바스크립트 객체이다.

-state는 직접 수정하면 안된다. (리액트에서 인지를 못하고 프로그램이 오작동할 수 있음)=>setState함수 사용하기

 

 

컴포넌트 재랜더링 3가지 경우

- props가 바뀌거나, state변경, 강제 업데이트

 

클래스 컴포넌트 생명주기(클래스컴포넌트는 이제 잘 안쓰니 흐름만 이해)

 

 

클래스컴포넌트 State와 생명주기 함수 사용하기 실습 예제 (교재p.185)

chapter_06파일

 

Notification.jsx

import React from "react";

const styles = {
    wrapper: {
        margin: 8,
        padding: 8,
        display: "flex",
        flexDirection: "row",
        border: "1px solid grey",
        borderRadius: 16,
    },
    messageText: {
        color: "black",
        fontSize: 16,
    },
};

class Notification extends React.Component {
    constructor(props) {
        super(props);

        this.state = {};
    }

    componentDidMount() {
        console.log(`${this.props.id} componentDidMount() called.`);
    }

    componentDidUpdate() {
        console.log(`${this.props.id} componentDidUpdate() called.`);
    }

    componentWillUnmount() {
        console.log(`${this.props.id} componentWillUnmount() called.`);
    }

    render() {
        return (
            <div style={styles.wrapper}>
                <span style={styles.messageText}>{this.props.message}</span>
            </div>
        );
    }
}

export default Notification;

 

NotificationList.jsx

import React from "react";
import Notification from "./Notification";

const reservedNotifications = [
    {
        id: 1,
        message: "안녕하세요, 오늘 일정을 알려드립니다.",
    },
    {
        id: 2,
        message: "점심식사 시간입니다.",
    },
    {
        id: 3,
        message: "이제 곧 미팅이 시작됩니다.",
    },
];

var timer;

class NotificationList extends React.Component {
    constructor(props) {
        super(props);

        this.state = {
            notifications: [],
        };
    }

    componentDidMount() {
        const { notifications } = this.state;
        timer = setInterval(() => {
            if (notifications.length < reservedNotifications.length) {
                const index = notifications.length;
                notifications.push(reservedNotifications[index]);
                this.setState({
                    notifications: notifications,
                });
            } else {
                this.setState({
                    notifications: [],
                });
                clearInterval(timer);
            }
        }, 1000);
    }

    render() {
        return (
            <div>
                {this.state.notifications.map((notification) => {
                    return (
                        <Notification
                            key={notification.id}
                            id={notification.id}
                            message={notification.message}
                        />
                    );
                })}
            </div>
        );
    }
}

export default NotificationList;

 

 

React Developer Tools 구글 확장프로그램 설치

https://chrome.google.com/webstore/detail/react-developer-tools/fmkadmapgofadopljbjfkapdkoienihi?hl=ko 

 

React Developer Tools

Adds React debugging tools to the Chrome Developer Tools. Created from revision 336ac8ceb on 7/13/2022.

chrome.google.com

 

 


Hook

갈고리 , web HOOK(어떤 작업이 수행될때 url을 넣어주면 그 url을 호출해준다.

-use 라고 처음에 붙여줘서 사용

 

 

 

 

1.useState

:state를 사용하기 위한 HOOK

2.useEffect

side effect를 수행하기 위한 HOOK

리액트의 함수컴포넌트에서 사이드이펙트를 실행할 수 있게 해주는 훅이다.

-side effect(부작용,버그) 인데 리액트에서는 효과,영향을 뜻함

effect는 랜더링이 끝난 이후에 실행되어야하는 작업/ 다른 컴포넌트에 영향을 미칠 수 있으며, 렌더링 중에는 작업이 완료될 수 없기 때문

 

effect function이 mount,unmount시에 단 한 번씩만 실행됨

의존성 배열을 생략하면 컴포넌트가 업데이트될때마다 실행

 

 

3.useMemo

Memoized value를 리턴하는 HOOK

Memoization: 비용이 높은 함수의 호출결과를 저장해놓았다가 새로 연산을 안하고 이전 저장한 호출결과를 곧바로 반환함

ex.1-10만 숫자를 메모했다가 더하라고 요청하면 기존 계산결과를 사용

 

최적화를 위해 사용

랜더링이 일어나는 동안 실행, 랜더링이 일어나는 동안 실행되면 안되는 작업은 넣으면 안됨

서버에서 데이터를 받아오거나 dom을변경하는 등의 작업은 랜더링이 일어나는 동안 실행되서는 안되기 때문에 넣으면 안됨(useEffect사용)

 

의존성배열이 빈 배열일 경우, 컴포넌트 마운트시에만 호출됨

 

4.useCallback

useMemo() 와 유사하지만 값이 아닌 함수를 반환한다는 것이 차이점이다.

특정 변수의 값이 변한 경우에만 함수를 다시 정의하도록 해서 불필요한 반복작업을 없애준다.

 

 

useCallback을 사용하지 않는 경우(비효율적)

 

5.useRef

특정컴포넌트에 접근할 수 있는 객체

.current라는 속성이 있는데 현재 레퍼런스(참조)하고 있는 엘리먼트를 의미한다.

 

'React > 소플 React 강의' 카테고리의 다른 글

[2022.07.30]소플 강의 정리 3  (0) 2022.07.30
[2022.07.29]React- 소플 강의 정리2  (0) 2022.07.29