HTML(Hypertext Markup Language) | XML(eXtensible Markup Language) | JSX(JavaScript XML) | |
---|---|---|---|
정의 | 하이퍼텍스트 마크업 언어 | 확장 가능 마크업 언어 | JavaScript XML |
목적 | 웹 페이지의 구조와 내용을 명시 | 데이터를 구조화하여 저장하고 전송 | 리액트에서 UI 구성 요소를 정의하고 렌더링 |
구문 | 고정된 기본 태그 세트 | 사용자 지정 태그 | 사용자 지정 태그 및 JavaScript 표현식 |
엄격성 | 태그 규칙이 느슨하며, 종료 태그 생략 가능 | 엄격한 태그 규칙 및 종료 태그 필수 | 엄격한 태그 규칙 및 종료 태그 필수 |
브라우저 지원 | 브라우저에서 직접 해석 및 렌더링 가능 | 브라우저에서 해석 가능, 스타일링 또는 변환 필요 | 브라우저에서 바로 해석 불가능, 컴파일 과정 필요 (Babel 등 사용) |
기준 | SPA (Single Page Application) | MPA (Multi Page Application) |
---|---|---|
정의 | 한 개의 웹 페이지에서 모든 내용과 기능을 제공하는 애플리케이션 | 여러 개의 웹 페이지로 구성되어 내용과 기능을 제공하는 애플리케이션 |
페이지 로딩 | 단 한 번의 페이지 로딩 후, 동적으로 데이터 받아 렌더링 | 각 페이지마다 로딩 및 렌더링이 필요 |
사용자 경험 | 빠른 인터랙션 및 부드러운 페이지 전환, 앱과 유사한 경험 | 전통적인 웹 서핑 경험, 페이지 간 전환 시 로딩 지연 발생 가능 |
개발 복잡성 | 프레임워크 (React, Angular, Vue 등) 사용 필요, 상태 관리 복잡하게 될 수 있음 | 서버에서 페이지를 생성하고 렌더링하는 방식으로 구현, 상대적으로 간단함 |
SEO 최적화 | 구현 및 필요한 조치가 복잡할 수 있음, 사전 렌더링 또는 서버 사이드 렌더링 필요 | 상대적으로 간단하게 구현 가능, 각 페이지마다 메타 데이터 활용 가능 |
데이터 요청 | AJAX를 통해 백엔드와 통신, 필요한 부분에만 데이터 요청 | 일반적으로 각 페이지 로딩 시 전체 데이터 요청 |
적합한 상황 | 복잡한 웹 애플리케이션, 사용자 중심의 경험을 제공하려는 경우 | 서버 기반 웹 사이트, 간단한 구조를 원할 경우, 전통적인 웹 서핑 경험 필요 |
SPA가 CSR이고, MPA가 SSR은 아니다!!!
페이지가 몇개냐 렌더링을 어디서 하냐에 따라 달라지는 것!!!
기준 | CSR (Client-Side Rendering) | SSR (Server-Side Rendering) | SSG (Static Site Generation) |
---|---|---|---|
정의 | 웹 브라우저에서 페이지 렌더링하는 방식 | 서버에서 페이지를 렌더링하여 클라이언트에 제공하는 방식 | 정적 페이지를 미리 생성하여 호스팅하는 방식 |
렌더링 위치 | 클라이언트에서 렌더링, 런타임에 최종 형태 생성 | 서버에서 렌더링, 빌드 시간에 최종 형태 생성 | 빌드 시간에 최종 형태 생성 및 저장 |
초기 로딩 속도 | 초기 렌더링 속도가 SSR에 비해 느리지만, 이후 페이지 전환은 빠름 | 빠른 초기 렌더링, TTFB(Time to First Byte) 낮음 | 빠른 초기 렌더링, 미리 생성된 페이지를 전송 |
SEO | 검색 엔진 최적화가 복잡할 수 있음, SSR이나 SSG에 비해 상대적으로 어려움 | 상대적으로 간단하게 구현 가능, 검색 엔진에 의한 크롤링 및 인덱싱에 유리 | 검색엔진 최적화가 용이, 정적 페이지로 인한 크롤링 및 인덱싱 용이 |
사용자 경험 | 사용자 중심의 인터랙션 및 부드러운 페이지 전환 가능 | 사용자에게 빠르게 콘텐츠를 제공할 수 있음 | 빠른 콘텐츠 전달 및 부드러운 사용자 경험, 변경이 없는 경우 효과적 |
캐싱 | 클라이언트에서 자원 캐싱 가능 | 캐싱 조치를 통한 성능 향상 가능 | 정적 페이지는 캐싱에 매우 유리함 |
적합한 상황 | 사용자 중심의 인터랙션 및 복잡한 웹 애플리케이션, 빠른 페이지 전환 필요 | 동적 콘텐츠, 빠른 초기 렌더링 요구, SEO 중요할 경우 | 정적 콘텐츠, 빠른 로딩 속도와 SEO가 중요한 경우, 빈번한 업데이트 없음 |
설명 | 예시 | |
---|---|---|
SPA + CSR | 페이지 전환 없이 클라이언트에서 모든 UI 변경을 처리하고 동적 렌더링하는 웹 애플리케이션 | 웹기반 게임, 웹 애플리케이션 대시보드 |
SPA + SSR (Next.js) | 초기 페이지 로딩 시 SSR을 사용해 빠르게 콘텐츠를 제공하고, 이후 페이지 전환은 CSR로 처리하는 애플리케이션 (Next.js 이용) | 프로그레시브 웹앱 (PWA), 소셜 미디어 플랫폼 |
MPA + SSR | 각 페이지가 서버에서 생성되어 전송되는 전통적인 웹 애플리케이션 | 전자상거래 웹사이트, 뉴스 웹사이트 |
MPA + CSR (부분적으로) | 일부 페이지 또는 페이지 요소를 동적으로 렌더링하기 위해 CSR이 결합된 전통적인 웹 애플리케이션 | 포털 사이트, 다목적 웹 사이트 |
SPA/MPA + SSG (Next.js) | 정적 콘텐츠 중심으로 빠른 로딩 속도와 SEO 최적화를 필요로 하는 웹사이트 (Next.js의 SSG 기능 사용) | 정적 블로그, 문서 및 기술 문서 웹사이트, 포트폴리오 웹사이트 |
함수형 프로그래밍
부수 효과(side effect)를 없애고 순수 함수(pure function)를 만들어 모듈화 수준을 높이는 프로그래밍 패러다임
side effect : 외부의 상태를 변경하는 것 또는 함수로 들어온 인자의 상태를 직접 변경하는 것
pure function : 부수효과가 없는 함수 즉, 어떤 함수에 동일한 인자를 주었을 때 항상 같은 값을 리턴하는 함수(동일 입력 - 동일 출력), 외부의 상태를 변경하지 않는 함수
// const greetCurry = (message) => (name) => `${name} ${message}`;
const greetCurry = (message) => {
return function greet(name) {
return `${name} ${message}!`;
};
};
// ----------------------------------------------------
// const morningGreet = greetCurry("좋은 아침입니다"); 는 아래처럼 처리된다.
const morningGreet = function greet(name) {
return `${name} 좋은 아침입니다`;
};
console.log(typeof morningGreet); // 그래서 데이터 타입이 함수인 것입니다.
// ----------------------------------------------------
morningGreet('범쌤'); // 는 아래처럼 처리됩니다.
function greet('범쌤') {
return `범쌤 안녕 좋은 아침이야!`;
};
// ----------------------------------------------------
greetCurry('안녕! 좋은 아침이야!')('범쌤');
// 위 코드는 아래처럼 처리됩니다.
// [1] 외부함수실행()
// 실행된함수결과 = greetCurry('안녕! 좋은 아침이야!')
// [2] 외부함수실행()이어서내부함수실행()
// 실행된함수결과('안녕! 좋은 아침이야!')
> pnpm create vite learn-react
Done. Now run:
cd learn-react
pnpm install
pnpm run dev
특징 | ES Modules (mjs) | CommonJS (cjs) |
---|---|---|
파일 확장자 | .mjs | .js, .cjs |
문법 구조 | import / export | require / module.exports or exports |
모듈 가져오기 | 동적수입 가능(import()) | 동적 수입 가능(require()) |
네이티브 지원 | 주요 브라우저 및 Node.js 14+ | Node.js 및 웹 패키지 번들러 지원 |
실행 타이밍 | 정적으로 실행 시, 시작 전 해석 | 동적으로 실행 시, 필요 시 해석 |
사용자 정의 스코프 | 한정적인 스코프 (클래스 외부로 접근 안됨) | 공유되는 스코프 |
Treeshaking 지원 여부 | 지원 (일부 패키지 번들러에서) | 미지원 |
Treeshaking: 불필요한 코드를 제거하여 번들 크기를 줄이는 최적화 프로세스
"dev": "vite --host --port=3000"
"scripts": {
"dev": "vite --host --port=3000",
"build": "vite build",
"lint": "eslint . --ext js,jsx --report-unused-disable-directives --max-warnings 0",
"preview": "vite preview"
},
--host
: vite가 개발 서버를 여러 호스트 이름으로 사용 가능하게 하여 네트워크 내의 다른 기기에서도 애플리케이션에 접근할 수 있다. 기본적으로 localhost로 사용--port=3000
: 개발 서버를 실행할 때 사용할 포트// React 모듈 불러오기
import * as React from "react";
// ReactDOM 모듈을 불러오기
import * as ReactDOM from "react-dom";
const appElement = React.createElement(
/* type */ "div",
/* props */ {
className: "App",
id: "reactAppElement",
"data-type": "React.ReactElement",
},
/* ... children => [child,child,child...] */
React.createElement(
"h1",
{
title: "React is Awesome",
},
"React는",
React.createElement("b", null),
"해"
)
);
React.DOM.div()
const appElement = React.DOM.div( { className: "App", id: "reactAppElement", "data-type": "React.ReactElement", }, React.DOM.h1( { title: "React is Awesome", }, "React는", React.DOM.b(null), "해" ) );
const appElementJSX = (
<div className="App" id="reactAppElement" data-type="React.ReactElement">
<h1 title="React is Awesome">
React는 <b>awesome</b>
</h1>
</div>
);
결과
JSX가 하는 일
- React 함수 컴포넌트의 조건
- 함수 이름은 첫글자가 대문자
- JSX를 반환
위 코드에서 각각의 요소들을 컴포넌트로 만들자!!
터미널에서
tree src
파일 구조 확인하기brew install tree tree src
src ├── App.jsx ├── assets │ └── react.svg ├── components │ ├── Description.jsx │ ├── Heading.jsx │ └── RenderingProcessList.jsx ├── main.backup.jsx └── main.jsx
Error 발생!!!
https://react.dev/reference/react/StrictMode
StrictMode
란?
React로 개발할 때 개발자가 실수 할 수 있는 문제를 알려줄거니까 <StrictMode>
로 <App />
을 감싸라
두 번 렌더링되는 StrictMode (콘솔로그 두 번 > 해결 방법)
children("페이지의 주요 콘텐츠"이라는 텍스트)이 렌더링되지 않음 어째서? props가 전달되지 않아서
html에서 href로 링크가 아닌 새로운 jsx로 라우팅
class 대신 className이라고 하는 이유는?
=> Javascript에서 class는 예약어이기 때문에
그럼 default는 어떻게 사용하지?
둘 다 쓰려면 어떻게 하지?
=> 구조 분해. (즉, 이름으로 내보낸건 {...}, 기본은 {} 없이!!!)
화살표 함수는 const 앞에 export default 붙여서 default 설정을 하지 못한다.
함수로 작성하자!!
scaffolding
boilerplate
JavaScript의 ES Modules(import와 export)를 사용하여 'react' 모듈로부터 모든 exported 내용을 React라는 이름의 객체로 가져온다.
즉, React 라이브러리의 모든 기능에 React 객체를 통해 접근할 수 있게된다.