* 프로그래머스, 타입스크립트로 함께하는 웹 풀 사이클 개발(React, Node.js) 5기 강의 수강 내용을 정리하는 포스팅.
* 원활한 내용 이해를 위해 수업에서 제시된 자료 이외에, 개인적으로 조사한 자료 등을 덧붙이고 있음.
환경 설정 : React.js 개발 환경 세팅.
타입과 모델 : Type의 정의, 이를 기반으로 하는 Model 작성.
데이터 흐름 : Data Flow. API 요청에서 렌더링까지 데이터의 흐름을 제어.
상태 관리 : 컴포넌트에서의 상태state 관리, 그리고 ContextAPI와 전역 상태 관리 라이브러리Redux를 활용.
UI 패턴 : 모달Modal / 무한 스크롤 / 슬라이드 쇼 / DropDown / 탭 등등.. 각종 UI 패턴의 구현 및 원리.
모바일 대응 : 반응형 웹은 기본.

19세기, 증기 보일러를 제작할 때 사용하던 틀.
나중에는 인쇄에 사용되는 인쇄판도 지창하는 용어로 발전.
이 단어가 컴퓨터 프로그래밍에서도 사용되게 되었다.
동작을 위해 반드시 포함되어야 하는 필수 내용, 보통 수정이 필요없이 작동하고 거의 그대로 가져다가 사용할 수 있는 내용들.
간단하게 말하자면 프로젝트 개발에 필요한 필수 요소들을 미리 세팅해놓고, 필요할 때마다 그대로 설치해주기만 하면 편하지 않겠는가?
React.js의 보일러플레이트Boilerplate는 통상 2가지. CRA와 Vite.
두 개념의 차이는 이전 포스팅 참조.
2025년을 기준으로 하자면.. CRA는 더 이상 사용하지 않는 것을 추천한다.
프로젝트 폴더 구조는 어떤 아키텍처를 사용하는지, 개발철학이 어떻게되는지에 따라 천차만별이다.
자세한 내용은 이전 포스팅 참조.
일단 이번 스프린트 프로젝트 구조는 아래와 같다.
pages - Router에 대응되는 Page 컴포넌트들.
- 여기 아래에 components들이 각각 위치한다.
components - 각 Page별 그리고 공통적으로 사용되는common component들.
utils - App에서 사용될 여러 함수들. Hook이 아니다.
hooks - Custom Hook으로 불리는 녀석들.
model - 이 서비스에서 다루는 데이터의 형태들을 정의.
api - API 함수들.
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject"
}
각각의 script들은 (NPM 기준) 'npm run ~'의 명령어로 동작한다.
start는 로컬 서버에서 App을 실행시킨다. 브라우저의 'http://localhost:3000' 주소로 접근 가능.
- 포트 번호는 .env 설정 후 PORT=4000처럼 설정하면 기본 포트를 변경할 수 있다.
- 코드에서 변경사항이 감지되면? Hot Module Replacement(HMR) 를 통해 자동으로 화면을 갱신해준다.
build는 src 디렉토리의 React 코드들을 최적화된 정적 파일로 변환하여 build/ 폴더에 생성.
- Webpack을 사용하여 코드 스플리팅(Code Splitting), 압축(Minification), 트리 셰이킹(Tree Shaking) 등의 최적화를 수행.
- build된 정적 파일들은 호스팅(예: Netlify, Vercel, Firebase Hosting, AWS S3)에 배포할 수 있다.
- npm run build -- --profile. React 16 이상에서는 프로파일링(Profiling) 모드를 활성화하여 성능 분석을 위한 정보를 얻을 수 있다.
test는 Jest 프레임워크를 사용하여 애플리케이션의 단위(Unit) 및 통합(Integration) 테스트를 실행.
- 기본적으로 "Watch Mode"가 활성화되어 변경 사항이 발생할 때마다 자동으로 테스트가 재실행.
- npm test -- --coverage 옵션을 사용하면 코드 커버리지 리포트를 생성할 수 있다.
eject는 CRA에서 제공하는 기본 Webpack, Babel, ESLint 등의 설정 파일을 프로젝트에 직접 노출.
- 이후에는 CRA의 관리 없이 커스텀 설정을 직접 변경가능.
- 다만, 이 작업은 되돌릴 수 없으며, eject를 실행하면 CRA의 업데이트를 더 이상 받을 수 없다.
- 일반적으로 CRA 내부 설정을 수정해야 하는 특별한 경우에만 사용.
라우터Router? 클라이언트가 요청하는 경로(URL)와 HTTP 메서드(GET, POST 등)에 따라 알맞은 처리를 수행하는 역할.
URL 경로와 요청 메서드 매핑 / 미들웨어 기능도 수행 / 모듈화 가능 등의 특징을 지닌다.
애플리케이션의 라우팅 시스템을 구성하는 핵심 요소.
자세한 내용은 이전 포스팅 참조.
도서 페이지에 필요한 모델은? 이번 프로젝트에서는 User / Book / Category / Cart / Order로 구성된다.
이전에도 언급했던 내용인데.. 개발자의 취향, 작업 요구사항 등에 따라 프론트엔드에서 데이터가 어떤 구조로 전달되는지 '아키텍처'를 구성하는 방법은 천차만별이다.
이번 프로젝트에서는..
컴포넌트 <-> Custom Hooks <-> API Function <-> 백엔드
CORS (Cross-Origin Resource Sharing)
기본적으로 프론트엔드와 백엔드 사이에서 데이터를 주고받을 때에는.. '같은 도메인'에서의 요청-응답만 허용하도록 되어있다.
그런데 실제 서비스에서 이용자와 서비스 제공자가 동일 위치일 수는 없다.
그래서.. 서로 다른 위치에서 요청-응답을 주고받는 것을 허용해줄 필요가 있다.
자세한 설명 및 해결 방법은 외부 포스팅 참조.
웹 애플리케이션이나 웹사이트에서 각 요소들이 화면에서 배치되는 방식.
UI(User Interface) 요소들을 어떻게 정렬하고, 배치하고, 구성할지를 정의하는 개념.
.container {
display: flex;
justify-content: center; /* 가로 중앙 정렬 */
align-items: center; /* 세로 중앙 정렬 */
}
.container {
display: grid;
grid-template-columns: 1fr 2fr 1fr;
gap: 10px;
}
@media (max-width: 768px) {
.container {
flex-direction: column;
}
}

프로젝트 전반적으로 적용해야 하는 글로벌 스타일(Global Styles)이 필요할 때에는?
styled-components에서 제공하는 createGlobalStyle를 사용하면 된다.
import { createGlobalStyle } from "styled-components";
const GlobalStyle = createGlobalStyle`
/* 생략... */
`;
export default GlobalStyle;
import React from "react";
import GlobalStyle from "./GlobalStyle";
function App() {
return (
<>
<GlobalStyle /> {/* 글로벌 스타일 적용 */}
<h1>Welcome to Styled Components!</h1>
</>
);
}
export default App;
테마?
여러 사이트에서 제공하고 있는, 화이트/다크 모드 같은 기능은 어떻게 구현해야하는가?
export const lightTheme = {
bgColor: "#ffffff",
textColor: "#333333",
accentColor: "#007bff",
};
export const darkTheme = {
bgColor: "#333333",
textColor: "#ffffff",
accentColor: "#ffcc00",
};
import React, { useState } from "react";
import { ThemeProvider } from "styled-components";
import { lightTheme, darkTheme } from "./theme";
import GlobalStyle from "./GlobalStyle";
function App() {
const [isDark, setIsDark] = useState(false);
return (
<ThemeProvider theme={isDark ? darkTheme : lightTheme}>
<GlobalStyle />
<button onClick={() => setIsDark(!isDark)}>Toggle Theme</button>
<h1>Styled Components Theme</h1>
</ThemeProvider>
);
}
export default App;