React 기초 · 1장 리액트 핵심

1장 · 리액트 핵심

React? 란? → JSX?컴포넌트?props?state? → 이벤트 처리 순서로, 훅을 배우기 전에 꼭 필요한 토대를 직접 실행하며 익힙니다.

React란?

React? 는 웹 화면(UI)을 만드는 자바스크립트 라이브러리입니다. 세 가지 핵심만 기억하세요.

핵심
컴포넌트? 로 나눈다 화면을 버튼·입력창·카드 같은 작은 조각으로 나눠 만들고 레고처럼 조립해요. 보통 함수 하나가 컴포넌트 하나.
선언적? 이다 "버튼을 찾아 글자를 지우고 다시 써라"가 아니라, "상태가 이러면 화면은 이렇게 보여야 한다"만 적습니다.
빠르다? 가벼운 가상 DOM으로 이전·새 화면을 먼저 비교해, 실제로 달라진 부분만 고쳐서 빠릅니다.
React는 인테리어 설계도. "거실에 소파, 그 옆에 램프"라고 원하는 결과만 적으면, 실제로 가구를 옮기고 설치하는 일(렌더링?)은 React가 알아서 합니다.

JSX 기초

JSX? 는 자바스크립트 안에서 HTML처럼 화면 모양을 적는 문법입니다. <div>안녕</div> 처럼 생겼지만 사실은 JS예요. 규칙 네 가지만 알면 됩니다.

규칙예시
{ } 안에 JS 값 넣기<p>안녕, {name}!</p>
classclassName<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는 읽기 전용

자식이 받은 props를 name = "다른값" 처럼 바꾸면 안 됩니다. 값을 바꿔야 하면 부모의 state 를 바꿔서 다시 내려보내요.

아래에서 nameemoji 값을 바꾸거나, <Greeting /> 을 하나 더 추가해보세요.

실제로 어디에 쓰나
  • 버튼·배지 재사용 — 색과 라벨만 props로 바꿔 "저장"·"삭제"·"진행중"·"완료"를 같은 컴포넌트로
  • 표에 데이터 내려주기 — 조회한 사용자 목록을 <DataTable rows={users} /> 로 전달
  • 동작(함수) 넘기기 — 행을 클릭하면 부모가 상세를 열도록 <Row onClick={openDetail} />
  • 제목·옵션 설정 — 모달 제목, 셀렉트박스 옵션 목록 등 화면마다 다른 값 주입

state 맛보기 — "바뀌면 화면도 바뀌는 값"

일반 변수 let count = 0 은 값을 바꿔도 화면이 그대로입니다. React가 "값이 바뀌었네"를 모르거든요. state?useState? 로 만들고, 전용 함수로 바꾸면 React가 자동으로 화면을 다시 그립니다(리렌더?).

일반 변수 (let)state (useState)
값 바꾸면 화면이?그대로 (안 바뀜)자동으로 다시 그려짐
바꾸는 법count = 1setCount(1)

아래 카운터에서 +1 을 눌러보세요. useState(0)010 으로 바꿔 실행해도 됩니다.

입력창과 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 반환
JSXJS 안에서 HTML처럼 쓰는 문법{} 값, className, 태그 닫기, 부모 하나
props부모 → 자식에게 주는 값읽기 전용, { name } 으로 받기
state바뀌면 화면도 바뀌는 값useState, setX 로만 변경
이벤트사용자 동작 처리onClick={fn} (괄호 붙이면 즉시 실행 버그)
TypeScript 표기는 지금 부담 갖지 마세요

코드에서 useState<number>(0)꺾쇠 <...>?(제네릭)나 e.target as HTMLInputElementas?(타입 단언) 같은 게 보여도, "타입을 알려주는 표시" 정도로 이해하고 넘어가도 됩니다. 지금은 React의 동작 흐름에 집중하세요.