https://www.inflearn.com/course/%EC%B2%98%EC%9D%8C-%EB%A7%8C%EB%82%9C-%EB%A6%AC%EC%95%A1%ED%8A%B8
강의를 참고했습니다.
웹 애플리케이션 또는 웹사이트가 하나의 페이지로 구성되어 있으며,
사용자와의 상호작용에 따라 필요한 부분만 동적으로 업데이트되는 형태를 말합니다.
페이지 로딩 시간 감소: 초기에 웹 애플리케이션의 필수 리소스를 한 번에 불러오고, 이후 데이터만 변경하여 화면을 업데이트하기 때문에 로딩 시간이 감소합니다.
사용자 경험 개선: 페이지 전환 없이 애플리케이션이 동작하기 때문에 데스크탑 애플리케이션과 유사한 사용자 경험을 제공할 수 있습니다.
front-end와 back-end의 분리: back-end는 API를 통해 데이터를 제공하는 역할에 집중하고, front-end는 이 데이터를 활용하여 UI를 구성합니다.
스크립트 언어의 한 종류입니다.
스크립트 언어는 간단한 작업을 빠르게 처리하는데 중점을 둔다면,
객체지향 언어는 시스템의 구조를 체계적으로 설계하는 데 중점을 둡니다.
하지만 하나의 프로그래밍 언어가 스크립트 언어와 객체지향 언어의 특성을 동시에 가질 수 있습니다. (Python)
var, let, const 이들 각각의 키워드는 변수의 스코프(유효 범위), 호이스팅(선언 위치), 재할당 가능 여부와 같은 특성을 가지고 있어, 사용 상황에 따라 적절하게 선택하여 사용해야 합니다.
var : 전통적인 변수 선언 키워드
스코프: var로 선언된 변수는 함수 스코프를 가집니다. 즉, 함수 내에서 선언된 var 변수는 함수 내 전체에서 유효하며, 함수 외부에서 선언된 var 변수는 전역 스코프를 가집니다.
호이스팅: var로 선언된 변수는 호이스팅되어 선언부가 함수의 최상단으로 끌어올려지는 것처럼 동작합니다. 단, 초기화는 실제 코드에 도달했을 때 이루어집니다.
재할당: 재할당이 가능합니다.
let : ES6부터 추가된 키워드
스코프: let으로 선언된 변수는 블록 스코프를 가집니다. 즉, 선언된 블록({}) 내부에서만 유효합니다.
호이스팅: let으로 선언된 변수도 호이스팅되지만, var와 달리 "일시적 사각지대(Temporal Dead Zone, TDZ)"에 빠져서 선언 이전에 접근하려 하면 참조 에러(ReferenceError)가 발생합니다.
console.log(myVar); // undefined
console.log(myLet); // ReferenceError: myLetVar is not defined
var myVar = 'var로 선언된 변수';
let myLet = 'let으로 선언된 변수';
재할당: 재할당이 가능합니다.
const : ES6부터 추가된 키워드, 불변의 상수를 선언할 때 사용합니다.
스코프: const로 선언된 상수도 블록 스코프를 가집니다.
호이스팅: const 또한 호이스팅은 되지만 TDZ에 의해 선언 전에는 접근할 수 없습니다.
재할당: const로 선언된 상수는 재할당이 불가능합니다. 선언 시 반드시 초기화해야 하며, 한 번 할당된 값은 변경할 수 없습니다.
function myFunction() {
var functionScoped = '저는 함수 스코프입니다';
if (true) {
var stillFunctionScoped = '저도 함수 스코프입니다';
}
console.log(functionScoped); // 출력: 저는 함수 스코프입니다
console.log(stillFunctionScoped); // 출력: 저도 함수 스코프입니다
}
myFunction();
console.log(functionScoped); // ReferenceError: functionScoped is not defined
function myFunction() {
if (true) {
let blockScoped = '저는 블록 스코프입니다';
const anotherBlockScoped = '저도 블록 스코프입니다';
}
console.log(blockScoped); // ReferenceError: blockScoped is not defined
console.log(anotherBlockScoped); // ReferenceError: anotherBlockScoped is not defined
}
myFunction();
호이스팅은 자바스크립트에서 변수 및 함수 선언을 코드의 맨 위로 끌어올리는 것처럼 동작하는 특성을 말합니다.
var, let, const로 선언된 변수들은 각기 다른 방식으로 호이스팅이 적용됩니다.
let a = 1;
let b = '1';
console.log(a == b); // true
console.log(a === b); // false, 자료형이 같아야합니다.
// function statement를 사용
// 함수 선언문은 호이스팅되어 코드의 상단으로 끌어올려집니다.
function sum(a, b) {
return a + b;
}
// arrow function expresstion
// 화살표 함수 표현식은 변수에 할당되는 값이므로 호이스팅되지 않습니다.
const multiply = (a, b) => {
return a * b;
}
UI를 만들기 위한 JavaScript 라이브러리입니다.
특정 프로그래밍 언어에서 자주 사용되는 특정 기능을 수행하는 함수나 도구들의 모음입니다.
개발자는 필요한 기능을 가진 라이브러리를 선택하여 자신의 프로젝트에 가져다 사용할 수 있습니다.
프레임워크
라이브러리
빠른 업데이트와 렌더링 속도
렌더링(Rendering)이란
- UI를 화면에 표시하는 과정을 말합니다.
- React에서 렌더링은 가상 DOM을 이용하여 실제 DOM과의 차이를 계산하고, 이를 실제 DOM에 반영하는 과정을 포함합니다.
- 렌더링 과정
1. 초기 렌더링:컴포넌트가 처음 화면에 나타날 때 발생,컴포넌트의render메소드가 호출되어JSX 코드를가상 DOM요소로 변환 후, 이를실제 DOM에 삽입하여 사용자가 볼 수 있는 UI를 만듭니다.
2.state또는props변경:컴포넌트의state또는props가 변경되면컴포넌트를 "재렌더링"합니다. 이는새로운 가상 DOM을 생성하고이전 가상 DOM과 비교하는 과정을 포함합니다.
3. 가상 DOM의 비교: React는이전 가상 DOM과새로운 가상 DOM을 비교하여 실제로 변경된 부분만을 찾아냅니다. 이 과정을"Diffing"이라고 하며, 성능 최적화를 위해 중요한 단계입니다.
4. 실제 DOM의 업데이트: 변경된 부분만을실제 DOM에 반영합니다. 최소한의 변경으로 UI를 최신 상태로 유지할 수 있습니다.
5.side effect발생: 렌더링이 완료된 후에는useEffect와 같은Hock을 통해 정의된side effect가 실행됩니다.
Virtual DOM은 웹페이지와 실제 DOM 사이에 중간 매개체 역할을 하고 있습니다.
작동원리
변경 감지: 사용자 인터랙션 또는 데이터 변경으로 인해 UI를 업데이트 해야 할 필요가 생겼을 때, 이 변경사항은 먼저 Virtual DOM에 적용됩니다.
차이 비교: 변경된 Virtual DOM과 이전 Virtual DOM 사이의 차이점을 계산합니다. 이 과정을 'Diffing'이라고 하며, 이를 통해 실제로 변경된 부분만 파악할 수 있습니다.
배치 업데이트: 변경된 부분만을 실제 DOM에 배치적으로 업데이트합니다. 이러한 방식은 브라우저의 리플로우(reflow)와 리페인트(repaint)를 최소화하여 성능을 개선합니다.
UI 렌더링: 최종적으로 사용자에게 보여지는 UI는 실제 DOM에 의해 렌더링됩니다.
React에서 컴포넌트는 UI의 독립적이고 재사용 가능한 부분들을 캡슐화하는 데 사용됩니다.
재사용성: 컴포넌트는 독립적인 단위로 구성되어 있어, 다른 프로젝트나 애플리케이션에서도 재사용할 수 있습니다.
캡슐화: 컴포넌트는 내부 로직을 숨기고, 인터페이스만을 제공하여 다른 컴포넌트와의 상호 작용을 단순화합니다.
독립성: 각 컴포넌트는 독립적으로 작동하며, 다른 컴포넌트의 내부 상태에 직접적으로 접근하지 않습니다.
JSX는 JavaScript와 XML, HTML을 합친 것이라 볼 수 있습니다.
JSX는 내부적으로 XML, HTML 코드를 JavaScript로 변환하는 과정을 거칩니다.
JSX를 사용하는 것이 필수는 아닙니다.
다만 JSX를 사용했을 때 생산성과 가독성이 올라가므로 사용하는 것이 좋습니다.
Injection Attacks을 방어 할 수 있습니다.
코드 예제
const element = (
<h1 className="greeting">
Hello, world!
</h1>
)
const element = React.createElement(
'h1', // element의 유형입니다. (type)
{ className: 'greeting' }, // 요소에 전달할 속성들의 객체입니다. (props)
'Hello, world!' // 요소의 자식으로 들어갈 내용입니다. (children)
// 문자열일 수도 있고, 다른 React 요소들일 수도 있으며, 또는 이들의 배열일 수도 있습니다.
)
const element = {
type: 'h1',
props: {
className: 'greeting',
children: 'Hello, world!'
}
}
js는 스크립트 언어인데 왜 컴파일 과정을 거치지?
- JavaScript는 전통적으로 인터프리터 언어이지만 현대적인 엔진에서는 JIT 컴파일을 포함한 복잡한 실행 과정을 거치며, JSX와 같은 확장 문법을 사용할 때는 해당 코드를 브라우저가 이해할 수 있는 JavaScript 코드로 "트랜스파일"하는 과정이 필요합니다.
JSX에서는 {}를 사용하면 무조건 JavaScript 코드가 들어간다고 외워두는게 좋습니다.
React 앱을 구성하는 가장 작은 블록들을 말합니다.
Element는 원래 DOM Element를 뜻합니다.
React Elements : DOM Elements의 가상표현JavaScript 객체 예시
{
type: 'button',
props: {
className: 'bg-green',
children: {
type: 'b',
props: {
children: 'Hello, element!'
}
}
}
}
실제로 랜더링 됐을 때 Element
<button class='bg-green'>
<b>
Hello, element!
<b>
</button>
DOM Elements : 실제 DOM 트리에 존재하는 HTML 엘리먼트를 나타내는 객체

Root DOM node
<div id="root"></div> <!-- Root DOM node -->
이 코드는 모든 React 앱에 필수적으로 들어가는 코드입니다.
이 div 태그 안에 React Element들이 렌더링 됩니다.
이 div 태그 안에 있는 모든 것이 React DOM에 의해서 관리됩니다.
root div에 React Element를 렌더링하는 코드
const element = <h1>Hello</h1>;
ReactDOM.render(element, document.getElementById('root'));
// ReactDOM.render(React Element, HTML Element(DOM Element))
// React Element를 DOM Element에 렌더링합니다.
Element는 불변성을 가지기 때문에 다시 생성해야 합니다.
function tick() {
const element = (
<div>
<h1>Hello</h1>
<h2>현재 시간: {new Date().toLocaleTimeString()}</h2>
</div>
);
ReactDOM.render(element, document.getElementById('root'));
}
setInterval(tick, 1000); // tick 함수를 1000ms마다 호출
React에서 모든 페이지는 Component로 구성되어 있고, 하나의 Component는 또 다른 여러 개의 Component의 조합으로 구성될 수 있습니다.
즉, 레고 블록을 조립하듯 Component들을 모아서 조립하는 느낌입니다.
Component 이름은 항상 대문자로 시작해야합니다.
React는 소문자로 시작하는 컴포넌트를 DOM 태그로 인식합니다.
const element = <welcome name="홍길동"/>; // (X) HTML 태그로 인식
const element = <Welcome name="홍길동"/>; // (O) React Compenent로 인식
Components는 클래스 컴포넌트와 함수 컴포넌트 두 가지 유형으로 나뉩니다.
함수 컴포넌트: 단순히 props를 입력받아서 렌더링할 요소를 반환하는 함수입니다.
React Hooks를 사용하여 상태관리와 생명주기 기능을 구현할 수 있습니다.
클래스 컴포넌트: React.Component를 상속받아 생성되며, render 메소드를 통해 렌더링할 요소를 반환합니다.
class Welcome extends React.Component{
render() {
return <h1>안녕, {this.props.name}</h1>;
}
}
React component는 개념적으로는 JavaScript의 함수와 비슷합니다.
일반적으로 JavaScript(또는 TypeScript) 클래스나 함수로 작성됩니다.

React component에서의 입력은 Props 이고 출력은 React element 가 됩니다.
Props는 properties(특성)의 줄임말로, Component에 데이터를 전달하는 방법입니다.
Component는 자신의 props를 수정할 수 없습니다.function ex1(account, amount){
account.total -= amount;
// 입력으로 받은 파라미터의 account객체의 total값을 수정하였습니다.
// Props는 읽기 전용이기 때문에 이러한 방식이 불가능합니다.
}
component를 다양한 props 값을 넣어 재사용 할 수 있습니다.props를 사용하는 방법은 이와 같습니다.
function Welcome(props) {
return <h1>안녕하세요, {props.name}님!</h1>;
}
function App() {
return <Welcome name="홍길동" />;
}
위 예제에서 App Component는 Welcome Component에 name이라는 prop을 홍길동이라는 값으로 전달합니다.