Vanilla JavaScript로 메모장의 기본 CRUD 기능을 구현했다.
지금까지 구현한 기능은 다음과 같다.
메모 추가
메모 목록 조회
메모 수정
메모 삭제
localStorage 저장
새로고침 후 데이터 유지
이제 다음 단계에서는 기존 메모장 기능을 React로 다시 구현해보려고 한다.
바로 React 프로젝트를 만들기 전에, 먼저 React에서 가장 기본이 되는 컴포넌트 개념을 정리해보려고 한다.
컴포넌트란?
컴포넌트는 쉽게 말하면 다음과 같다.
화면의 한 부분을 담당하는 JavaScript 함수
지금 만든 메모장 화면을 보면 여러 영역으로 나눌 수 있다.
전체 앱
메모 입력 영역
메모 목록 영역
메모 카드 하나
Vanilla JavaScript 단계에서는 HTML 안에 화면 구조가 전부 같이 들어 있었다.
<div class="app">
<div class="memo-form">...</div>
<div class="memo-list">...</div>
</div>
React에서는 이런 화면 구조를 함수 단위로 나눌 수 있다.
function App() {
return (
<div className="app">
<MemoForm />
<MemoList />
</div>
);
}
여기서 각각의 역할은 다음과 같다.
App
= 전체 화면 컴포넌트
MemoForm
= 메모 작성 영역 컴포넌트
MemoList
= 메모 목록 영역 컴포넌트
즉, React에서는 화면을 하나의 큰 HTML 덩어리로 보는 것이 아니라, 여러 컴포넌트를 조립해서 만드는 방식으로 본다.
왜 컴포넌트로 나누나?
한 파일에 모든 UI를 다 작성하면 처음에는 편하다.
하지만 기능이 조금만 커져도 코드가 복잡해진다.
메모장만 봐도 다음 코드들이 한 곳에 섞일 수 있다.
입력창 코드
버튼 코드
메모 목록 코드
수정 코드
삭제 코드
저장 코드
처음에는 별문제가 없어 보이지만, 나중에는 어디가 입력 영역이고 어디가 목록 영역인지 구분하기 어려워질 수 있다.
컴포넌트로 나누면 역할이 더 명확해진다.
MemoForm
= 제목/내용 입력, 추가 버튼
MemoList
= 메모 목록 출력
MemoItem
= 메모 카드 하나, 수정/삭제 버튼
즉, 컴포넌트는 HTML을 기능별 조각으로 나누는 느낌이다.
현재 메모장을 React 컴포넌트로 나누면
현재 메모장 구조를 React 컴포넌트로 나누면 다음과 같이 볼 수 있다.
App
- 전체 상태 memos를 가지고 있음
- addMemo, editMemo, deleteMemo 함수 가지고 있음
MemoForm
- 제목/내용 입력
- 추가 버튼
MemoList
- memos 배열을 받아서 목록 출력
MemoItem
- 메모 하나 표시
- 수정/삭제 버튼
구조로 보면 다음과 같다.
App
├─ MemoForm
└─ MemoList
├─ MemoItem
├─ MemoItem
└─ MemoItem
여기서 중요한 점은 App이 전체 데이터를 가지고 있다는 것이다.
Vanilla JavaScript에서는 memos 배열을 전역 변수처럼 사용했다.
let memos = [];
React에서도 처음에는 비슷하게 App 컴포넌트가 메모 목록 데이터를 가지고 시작하면 된다.
그다음 MemoForm, MemoList, MemoItem으로 필요한 값을 내려보내는 식으로 구조를 잡을 수 있다.
React를 처음 시작할 때 모든 컴포넌트를 처음부터 나누려고 하면 오히려 헷갈릴 수 있다.
그래서 처음에는 App 컴포넌트 하나에 전체 기능을 작성해도 된다.
순서는 다음과 같다.
1. App 컴포넌트 하나에서 메모장 구현
2. MemoForm 컴포넌트 분리
3. MemoList 컴포넌트 분리
4. MemoItem 컴포넌트 분리
처음부터 완벽한 구조를 만들려고 하기보다, 먼저 동작하게 만들고 그다음에 역할별로 나누는 방식이 더 이해하기 쉽다.
Vanilla JS와 React 비교
Vanilla JavaScript에서는 메모 카드를 만들 때 직접 HTML 요소를 생성했다.
const memoCard = document.createElement('div');
memoCard.innerHTML = `
<h3>${memo.title}</h3>
<p>${memo.content}</p>
`;
memoContainer.appendChild(memoCard);
즉, JavaScript로 HTML 요소를 직접 만들고, 직접 화면에 붙였다.
React에서는 컴포넌트 함수가 JSX를 반환한다.
function MemoItem() {
return (
<div className="memo-card">
<h3>제목</h3>
<p>내용</p>
</div>
);
}
겉으로 보면 HTML처럼 생겼지만, 실제로는 JavaScript 안에서 작성하는 JSX 문법이다.
정리하면 다음과 같다.
Vanilla JS
= JS로 HTML 요소를 직접 만들고 DOM에 붙인다.
React
= 컴포넌트 함수가 JSX를 반환하고, React가 화면을 갱신한다.
이 차이가 React를 배우면서 가장 먼저 익숙해져야 하는 부분이다.
class와 className
React에서는 HTML의 class 대신 className을 사용한다.
Vanilla HTML에서는 이렇게 작성했다.
<div class="app"></div>
React JSX에서는 이렇게 작성한다.
<div className="app"></div>
처음에는 어색하지만, JSX가 HTML 그대로가 아니라 JavaScript 안에서 사용하는 문법이기 때문에 className을 사용한다고 이해하면 된다.
핵심은 다음과 같다.
컴포넌트는 화면 조각을 담당하는 함수다.
React 화면은 컴포넌트들을 조립해서 만든다.
처음에는 App 하나로 시작해도 된다.
나중에 MemoForm, MemoList, MemoItem으로 나누면 된다.
지금 단계에서는 React의 모든 개념을 한 번에 이해하려고 하기보다, 기존에 만든 메모장 화면을 어떻게 컴포넌트로 나눌 수 있는지만 먼저 잡으면 된다.
이제부터는 같은 메모장 기능을 React 방식으로 다시 구현하면서, 기존 JavaScript 방식과 어떤 점이 다른지 비교해볼 예정이다.
'Project > Memo Evolution' 카테고리의 다른 글
| #12 React 프로젝트 시작과 입력값 상태 관리 (0) | 2026.06.16 |
|---|---|
| #11 React 시작하기 (0) | 2026.06.15 |
| #9 JavaScript 코드 구조 정리하기 (0) | 2026.06.15 |
| #8 메모 수정 기능 구현 (0) | 2026.06.13 |
| #7 localStorage로 메모 저장하기 (0) | 2026.06.13 |