=> 나의 주력 트랙은 백엔드 트랙이기는 하지만 프런트의 코드를 아얘 몰라서는 안된다고 생각을 했다. 백엔드와 프런트엔드는 독립적이면서도 종속적인 부분이 있다고 생각한다. 이번에 리액트를 정리해보면서 조금 여유있을 때 한번 배워보고 싶다는 생각을 하게 되었다.
라이브러리 : 특정 프로그래밍 언어에서 자주 사용되는 기능들을 모아서 정리해 놓은 모음집
리액트 : 자바스크립트 UI 라이브러리 (사용자 인터페이스를 위한)
가장 큰 차이 : 프로그램의 흐름에 대한 제어 권한
프레임워크 : 흐름의 제어를 개발자가 아닌 프레임워크가 가짐
라이브러리 : 흐름의 제어를 하지 않고 개발자가 필요한 부분만 필요할 때 가져다 사용하는 형태
1) 빠른 업데이트 및 렌더링 (VIrtual DOM 을 이용하기 때문)
=> DOM : Document Object Model 로서 웹페이지를 정의하는 하나의 객체
(하나의 웹사이트에 대한 정보를 모두 담고 있는 큰 그릇)
=> Virtual DOM : 가상의 DOM으로서 웹페이지와 실제 DOM 사이에서 중간 매개체 역할을 하는 것
화면이 업데이트 된다 == DOM 이 수정된다.
DOM 을 직접 수정한다는 것은 큰 비용이 든다는 것이다. (모든 페이지 확인)
반면 리액트는 모든 DOM 이 아니라 수정이 필요한 부분만 찾아서 수정
2) 컴포넌트 기반의 구조
하나의 페이지가 여러개의 컴포넌트 조합으로 구성될 수 있다.
(하나의 컴포넌트 안에 여러 컴포넌트가 존재할 수 있다.)
=> 재사용성 GOOD (But 재사용 시 의존성 및 호환성 문제가 발생 가능)
=> 개발 기간이 단축된다. (버그 찾기도 좋다. (의존성이 낮다는 의미))
리액트의 관점 : 하나의 컴포넌트가 계속 사용 가능하다.
3) react native 로 확장 가능 (모바일 전용)
1) 방대한 학습량
2) 계속 해서 바뀌기 때문에 꾸준한 공부 필요
3) 높은 상태관리 복잡도 (state 관리 까다로움)
<html>
<head>
<title>태우 블로그</title>
<link rel="stylesheet" href="styles.css">
</head>
<body>
<h1>안녕하세용</h1>
<!--이 태그가 dom container 로 사용 될 예정-->
<div id="root"></div>
<!-- 리액트 가져오기 -->
<script src="https://unpkg.com/react@17/umd/react.development.js" crossorigin></script>
<script src="https://unpkg.com/react-dom@17/umd/react-dom.development.js" crossorigin></script>
<!-- 리액트 컴포넌트 가져오기-->
<script src="MyButton.js"></script>
</body>
</html>
h1{
color: green;
font-style: italic;
}
function MyButton(props){
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);
// 간단한 리액트 함수 컴포넌트
script태그를 통해 리액트를 가져옴으로서 리액트 컴포넌트를 MyButton.js 에 만들고 렌더링 하였다.
하지만 이러한 방법은 실수 유발및 불안정 하기 때문에create-react-app을 사용할 것이다. (현재 코드 전체 이해 필요 x)
앞선 방법과 달리 react 가 적용되어 있는 상태에서 개발을 시작해본다.
npx 명령어를 통해 npm의 명령어를 바로 실행 할 수 있도록 한다.

(위와 같이 리액트 애플리케이션을 준비 할 수 있다.)
=> 생성 해봄 아래와 같이

cd my-app: 'my-app' 디렉토리로 이동
npm start: 애플리케이션 실행

A syntax extension to JavaScript 로서 js 의 확장 문법이다. (JavaScript + XML/HTML)예제 코드
const element = <h1>Hello, world!</h1>;
위와 같이 javascript 코드와 html 코드가 결합된 jsx코드이다.
(앞으로의 리액트 코드에 많이 나올 것이다.)

위와 같은 React 내부의 함수를 통해 JSX 코드를 JS 코드로 변환한다.

위 Hello 클래스에서 사용된 JSX코드를 아래의 ReactDOM이 JS코드로 렌더링 하고 있는 것이다.

순수한 JS 를 사용함. React에서는 JSX를 사용하면 위와 같은
createElement를 사용하도록 된다.

위 두 코드는 동일하다. 그리고 위 결과로 아래의 javascript 객체가 생성된다. 이것이
React element


type: div, span 과 같은 html 태그 또는 다른 react 컴포넌트
props: 리액트 컴포넌트의 속성들이 들어간다.
children: 현재 element 의 자식 element
=> JSX는 필수가 아니다. (createElement로 대체 가능) 장점이 있기 때문에 사용하는 것이다. (가독성 UP)
1) 간결한 코드
2) 가독성 향상 (의미 전달 UP) => 버그 발견이 쉬움

간결하며 가독성이 증가한다.
3) Injection Attacks 방어
=> 입력 창에 소스 코드를 입력하여 해당 코드가 실행되도록 하는 해킹 방법

위
title이라는 변수에 잠재적으로 보안 위험이 있는 코드가 삽입됨
{}를 통해서 임베딩 하고 있는데 이때 reactDom 은 임베딩된 값을 문자열로 변환하며 이때 값은 명시적으로 선언된 값이 아니면 {} 사이에 들어가지 못함


기본적으로 위와 같은 형식을 가지며 {} 안에 js 코드를 넣는 방식이다.

또한 위와 같이 함수를 호출 할 수도 있다.

태그의 속성에 값을 넣는 방법

그냥 html 처럼 상위태그가 하위태그들을 감싸도록 하면 된다.
import React from "react";
function Book(props){
return(
<div>
<h1>{`이 책의 이름은 ${props.name} 입니다.`}</h1>
<h2>{`이 책은 총 ${props.numOfPage}페이지로 이뤄져 있습니다.`}</h2>
</div>
)
}
export default Book;
import React from "react";
import Book from "./Book";
function Library(props){
return (
<div>
<Book name="처음 만난 파이썬" numOfPage={300}></Book>
<Book name="처음 만난 AWS" numOfPage={400}></Book>
<Book name="처음 만난 리액트" numOfPage={500}></Book>
</div>
)
}
export default Library;
import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';
import Library from './ch03/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();
Library 컴포넌트를 가져와서 react-dom 을 사용하여 root DOM 노드에 렌더링 하도록 하는 코드이다.


Book.js 인데 코드가 많고 가독성이 떨어진다.
1) DOM Elements (html 요소)

2) React Elements
=> 리액트 개발 초창기 화면에 나타나는 내용을 기술하는 자바스크립트 객체를 일컫는 말이 있었다. 그게 바로 (Descriptor) 라고 불림
=> 하지만 Descriptor 가 최종적으로 나타나는 형태는 DOM Element의 형태였다. 따라서 이를 Element라고 통일성을 주기 위해 함
React Elements vs DOM Elements
위 처럼 Virtual DOM 에 존재하면
React Elements, Browser DOM에 존재하면DOM Elements가 되는 것이다.
(보통 브라우저 돔이 더 크고 무겁다. 이 강의에서 Elements 는 기본적으로 react Elements 가 될 것이다.)

위 코드는
react Element가 생성되는 과정을 보여준다. 우변 식이
react 의createElement함수를 이용하여react element로 만들어진다. 그리고 이것이 나중에DOM Elements로서 우리가 볼 수 있게 된다.
1) 일반적인 html의 경우
button을 나타내는 element 살펴보기 (react Elements)

위 객체가 렌더링이 되면 아래와 같은 DOM Elements 가 된다.
(DOM Elements)

2) react 컴포넌트의 경우

=> 이전 html 과의 차이는 type이 문자열이 아닌 컴포넌트의 이름이 있다는 것
=> 그리고 이 객체를 만드는 것이 바로 createElement 함수 이다.
3) createElement 함수가 동작하는 과정

두개의 컴포넌트가 있으며
ConfirmDialog컴포넌트가Button컴포넌트를 포함하고 있다. 그리고 위 코드가 createElement에 의해 객체로 되면 아래와 같이 될 것이다.


따라서 화면에 변경된 Elements를 보여주고 싶으면 기존 Elements를 변경하는 것이 아니라 새로운 Elements 를 생성하고 기존 Elements 와 변경하면 된다.

위 동그라미 하나하나 가 Elements 이며 빨간색이 변경할 Element 이다. Virtual DOM 에서는 하나하나 바뀌며 이후 렌더링을 통해 Browser DOM 이 바뀐다.

모든 리액트에 들어가는 아주 중요한 코드이다. 이 div 태그 내부의 모든 것 (Elements) 들이 react DOM 에 의해서 관리되기 때문


element라는 react Elements 를 생성하고 그것을 root div 에 렌더링하는 코드로서 위 코드가 virtualDOM 에서 BrowserDOM 으로 이동하는 것이다.

현재 시간을 포함하는 Element를 생성하여 root div 에 렌더링하는 역할
그리고 setInterval을 이용하여 매초 함수를 호출하고 있다.
(내부적으로는 생성된 Element 가 변경되는 것이 아닌 매초 새로운 Element를 생성하고 있다는 것이다.)
setInterval(() => {
ReactDOM.render(
<React.StrictMode>
<Clock />
</React.StrictMode>,
document.getElementById('root')
);
}, 1000);
강의와 동일하게 하면 오류 발생 (React 18 이상부터는 ReactDOM.render 가 제거되었다.
ReactDOM.createRoot와root.render를 사용해야 한다.
const root = ReactDOM.createRoot(document.getElementById('root'));
setInterval(() => {
root.render(
<React.StrictMode>
<Clock />
</React.StrictMode>,
document.getElementById('root')
);
}, 1000);
위와 같이 해야 한다.
결과 : 

=> 위와 같이 root div에 렌더링 된 것을 확인 가능 (변경이 아닌 생성!!@@)