1장 · 리액트 핵심
React? 란? → JSX? → 컴포넌트? → props? → state? → 이벤트 처리 순서로, 훅을 배우기 전에 꼭 필요한 토대를 직접 실행하며 익힙니다.
React란?
React? 는 웹 화면(UI)을 만드는 자바스크립트 라이브러리입니다. 세 가지 핵심만 기억하세요.
| 핵심 | 뜻 |
|---|---|
| 컴포넌트? 로 나눈다 | 화면을 버튼·입력창·카드 같은 작은 조각으로 나눠 만들고 레고처럼 조립해요. 보통 함수 하나가 컴포넌트 하나. |
| 선언적? 이다 | "버튼을 찾아 글자를 지우고 다시 써라"가 아니라, "상태가 이러면 화면은 이렇게 보여야 한다"만 적습니다. |
| 빠르다? | 가벼운 가상 DOM으로 이전·새 화면을 먼저 비교해, 실제로 달라진 부분만 고쳐서 빠릅니다. |
JSX 기초
JSX? 는 자바스크립트 안에서 HTML처럼 화면 모양을 적는 문법입니다.
<div>안녕</div> 처럼 생겼지만 사실은 JS예요. 규칙 네 가지만 알면 됩니다.
| 규칙 | 예시 |
|---|---|
① { } 안에 JS 값 넣기 | <p>안녕, {name}!</p> |
② class → className | <div className="card"> |
| ③ 모든 태그는 닫기 | <img /> <br /> |
| ④ 부모 하나로 감싸기 | <> ... </> (Fragment) |
아래 코드에서 name 이나 식 {1 + 2 + 3} 을 바꾸고 ▶ 실행 해보세요. {} 안에는 변수도, 계산식도 넣을 수 있어요.
컴포넌트는 하나의 부모만 반환할 수 있어요. 형제 요소가 여럿이면 <div> 로 감싸거나,
화면에 불필요한 div를 안 만들려면 빈 태그 <>...</>(Fragment)로 감쌉니다.
- 값 끼워 넣기 — 사용자 이름·장비 코드·검수 상태를 화면에 표시:
<td>{user.name}</td> - 조건부 표시 — 권한 있는 사람에게만 "삭제" 버튼:
{isAdmin && <DeleteButton />} - 목록 그리기 — 재고 목록을
items.map(...)으로 표의 행으로 펼치기 - 스타일 입히기 —
className으로 상태별 배지 색 지정(진행중·완료 등)
컴포넌트 만들기
컴포넌트? 는 JSX를 반환하는 함수입니다.
규칙은 단 하나, 이름을 대문자로 시작하는 것. 만든 컴포넌트는 <Hello /> 처럼 태그로 씁니다.
React는 소문자 태그 <div> 는 진짜 HTML로, 대문자 태그 <Hello> 는 내가 만든 컴포넌트로 구분합니다.
소문자로 만들면 컴포넌트로 인식하지 못해요.
아래는 작은 컴포넌트 Hello 를 만들어 App 안에서 두 번 쓰는 예제입니다.
- 화면 조각으로 나누기 — 검색 영역·표·페이지네이션을
SearchForm·DataTable·Pager컴포넌트로 분리 - 반복되는 UI 묶기 — 상태 배지(
StatusBadge), 빈 화면 안내(EmptyState) 처럼 여러 페이지에서 재사용 - 페이지 단위 — 사용자 관리·장비 관리·주문 같은 화면 하나하나가 큰 컴포넌트
- 레이아웃 틀 — 사이드바·헤더처럼 모든 화면이 공유하는 껍데기
props — 부모가 자식에게 주는 값
같은 컴포넌트라도 매번 다른 내용을 보여주고 싶을 때 props? 를 씁니다.
HTML 속성처럼 <Hello name="경수" /> 로 넘기면, 자식은 구조 분해 { name } 으로 받아요.
자식이 받은 props를 name = "다른값" 처럼 바꾸면 안 됩니다.
값을 바꿔야 하면 부모의 state 를 바꿔서 다시 내려보내요.
아래에서 name 과 emoji 값을 바꾸거나, <Greeting /> 을 하나 더 추가해보세요.
- 버튼·배지 재사용 — 색과 라벨만 props로 바꿔 "저장"·"삭제"·"진행중"·"완료"를 같은 컴포넌트로
- 표에 데이터 내려주기 — 조회한 사용자 목록을
<DataTable rows={users} />로 전달 - 동작(함수) 넘기기 — 행을 클릭하면 부모가 상세를 열도록
<Row onClick={openDetail} /> - 제목·옵션 설정 — 모달 제목, 셀렉트박스 옵션 목록 등 화면마다 다른 값 주입
state 맛보기 — "바뀌면 화면도 바뀌는 값"
일반 변수 let count = 0 은 값을 바꿔도 화면이 그대로입니다. React가 "값이 바뀌었네"를 모르거든요.
state? 는 useState? 로 만들고,
전용 함수로 바꾸면 React가 자동으로 화면을 다시 그립니다(리렌더?).
| 일반 변수 (let) | state (useState) | |
|---|---|---|
| 값 바꾸면 화면이? | 그대로 (안 바뀜) | 자동으로 다시 그려짐 |
| 바꾸는 법 | count = 1 | setCount(1) |
아래 카운터에서 +1 을 눌러보세요. useState(0) 의 0 을 10 으로 바꿔 실행해도 됩니다.
입력창과 state를 연결하면 제어 컴포넌트? 가 됩니다. 입력값을 state가 쥐고 있어 검증·초기화가 쉬워요. 입력해보세요.
useState 같은 훅? 의 자세한 사용법(useEffect, 정리 함수 등)은
2장에서 직접 실행하며 깊게 다룹니다. 지금은 "바뀌면 화면이 바뀌는 값"이라는 느낌만 잡으면 충분해요.
- 검색어 입력 — 사용자/장비 검색창에 친 글자를 담기:
const [q, setQ] = useState("") - 모달·상세 열림 — 상세 Sheet나 등록 모달이 열렸는지:
const [open, setOpen] = useState(false) - 선택한 행·탭 — 표에서 고른 주문 행, 지금 보고 있는 탭 번호
- 체크박스 선택 — 일괄 삭제를 위해 체크한 항목들의 목록
이벤트 처리
버튼 클릭·입력 변화 같은 사용자 동작은 onClick, onChange 속성에 함수를 넘겨 처리합니다.
(HTML의 onclick 과 달리 카멜케이스 onClick 으로 씁니다.)
{fn} vs {() => fn()}onClick={fn} 은 "클릭하면 실행할 함수"를 넘기는 것. 반면 onClick={fn()} 처럼 괄호를 붙이면
렌더하는 순간 바로 실행되고 그 반환값이 넘어가 버립니다(즉시 호출 버그). 인자가 필요하면
onClick={() => greet("경수")} 처럼 화살표 함수로 감싸세요.
아래 두 버튼을 비교해보세요. 위 버튼은 정상, 아래 "❌ 버그" 버튼은 누르기도 전에 즉시 실행됩니다(실행하면 바로 메시지가 뜸).
- 행 클릭으로 상세 열기 — 표의 한 행을 클릭하면 그 장비/주문의 상세 화면을 띄움
- 폼 제출 — 등록·수정 화면에서 "저장" 버튼의
onSubmit으로 서버에 보내기 - 입력 변화 감지 — 검색창
onChange로 글자를 state에 반영 - 삭제·취소 확인 — "삭제" 버튼
onClick에서 확인 후 처리
한눈에 정리
| 개념 | 한 줄 요약 | 핵심 |
|---|---|---|
| 컴포넌트 | 화면을 이루는 조각 | 함수 + 대문자 이름 + JSX 반환 |
| JSX | JS 안에서 HTML처럼 쓰는 문법 | {} 값, className, 태그 닫기, 부모 하나 |
| props | 부모 → 자식에게 주는 값 | 읽기 전용, { name } 으로 받기 |
| state | 바뀌면 화면도 바뀌는 값 | useState, setX 로만 변경 |
| 이벤트 | 사용자 동작 처리 | onClick={fn} (괄호 붙이면 즉시 실행 버그) |
코드에서 useState<number>(0) 의 꺾쇠 <...>?(제네릭)나
e.target as HTMLInputElement 의 as?(타입 단언) 같은 게 보여도,
"타입을 알려주는 표시" 정도로 이해하고 넘어가도 됩니다. 지금은 React의 동작 흐름에 집중하세요.