Step 0. src/App.jsx 작성
먼저 아주 단순한 버튼부터 만들어보자.
그러기 위해 기존의 src/App.jsx 코드를 지우고 다음 코드로 변경한다.
function App() {
function handleClick() {
console.log("버튼 클릭");
}
return (
<div>
<button onClick={handleClick}>클릭</button>
</div>
);
}
export default App;
브라우저를 통해 확인해 보면

개발자 도구의 Console 탭을 열고 버튼을 눌러보자.

여기서 중요한 부분은
<button onClick={handleClick}>클릭</button>
으로 의미는 "이 버튼이 클릭되면 handleClick 함수를 실행해라." 라는 의미이다.
Step 1. React의 이벤트
웹 화면에서는 사용자가 여러 행동을 할 수 있다.
버튼 클릭
텍스트 입력
폼 제출
마우스 움직임
키보드 입력
React에서는 이런 행동에 함수를 연결한다.
예를 들어,
function App() {
function sayHello() {
alert("안녕하세요");
}
return (
<button onClick={sayHello}>
인사하기
</button>
);
}
에서 버튼 클릭이라는 이벤트를 발생시키면
sayHello()
가 실행되고 결과적으로 "안녕하세요"라는 알림이 뜬다.
Step 2. 화면에 출력되는 값을 일반 변수로 바꾸면 안 될까?
이제 클릭 횟수를 화면에 보여주고 싶다고 해보자.
처음에는 이런 코드가 떠오를 수 있다.
function App() {
let count = 0;
function handleClick() {
count = count + 1;
console.log(count);
}
return (
<div>
<p>{count}</p>
<button onClick={handleClick}>
+1
</button>
</div>
);
}

버튼을 누르면 콘솔에서는

처럼 값이 변하지만 화면의 숫자는 계속해서 0이다.
왜 그럴까?
React는 일반 JavaScript 변수의 변화를 보고 화면을 다시 그리지 않기 때문이다.
이 문제를 해결하기 위해 사용하는 것이 State이다.
Step 3. 상태(State)란?
State는 아주 간단하게 생각하면 컴포넌트가 기억하고 있는 값이다.
그리고 중요한 특징이 있다.
State가 변경되면 React가 화면을 다시 렌더링한다.
그러므로
- 일반 변수 변경 → React는 관심 없음
- State 변경 → React가 다시 렌더링
이라고 이해하면 된다.
Step 4. useState
React에서 State를 만들 때 가장 기본적으로 사용하는 것이 useState이다.
import { useState } from "react";
function App() {
const [count, setCount] = useState(0);
return (
<div>
<p>{count}</p>
</div>
);
}
export default App;
여기서 useState(0)은 처음 count가 0이라는 뜻으로 계속해서 유지되는 값이 아니다.
이제 이 코드에서 count와 setCount를 나눠서 봐보자.
- count → 현재 값
- setCount → count 값을 변경하는 함수
따라서
setCount(10);
을 실행하면 count → 10이 된다.
그리고 React가 화면을 다시 렌더링 한다.
Step 5. 첫 번째 State 실습
이제 카운터를 만들어 보자.
import { useState } from "react";
function App() {
const [count, setCount] = useState(0);
function handleClick() {
setCount(count + 1);
}
return (
<div>
<h1>카운터</h1>
<p>현재 숫자: {count}</p>
<button onClick={handleClick}>+1</button>
</div>
);
}
export default App;

버튼을 클릭해 보면

화면의 숫자가 변경되는 것을 확인할 수 있다.
이 부분이 React의 핵심 흐름이다.
사용자가 버튼 클릭
↓
handleClick 실행
↓
setCount(count + 1)
↓
state 변경
↓
App 컴포넌트 다시 실행
↓
새로운 count를 이용해 JSX 생성
↓
화면 업데이트
Step 6. State가 바뀌면 React가 컴포넌트를 다시 실행한다.
App 컴포넌트가 시작되는 경우에 콘솔에 문자열이 출력되도록 코드를 수정해 보자.
function App() {
console.log("App 실행"); // App 시작부분에 삽입
const [count, setCount] = useState(0);
...
그다음 브라우저에서 실행하여 처음 화면에서 콘솔을 확인해 보면 "App 실행" 문자열이 출력되는 것을 볼 수 있고
버튼을 클릭하여 state를 변경하면

컴포넌트가 다시 실행되며 콘솔에 문자열이 다시 출력되는 것을 볼 수 있다.
즉,
state 변경
↓
App() 다시 실행
↓
새 JSX 계산
↓
화면 반영
이다.
여기서 한 가지 오해는 피해야 한다.
state가 변경되면 React가 브라우저 페이지 전체를 새로고침하는 것은 아니다.
필요한 UI 변경을 React가 처리한다.
Step 7. 증가, 감소, 초기화 버튼 만들기
import { useState } from "react";
function App() {
const [count, setCount] = useState(0);
function increase() {
setCount(count + 1);
}
function decrease() {
setCount(count - 1);
}
function reset() {
setCount(0);
}
return (
<div>
<h1>{count}</h1>
<button onClick={decrease}>-1</button>
<button onClick={reset}>초기화</button>
<button onClick={increase}>+1</button>
</div>
);
}
export default App;
Step 8. State는 여러 개 만들 수 있다
컴포넌트에는 State가 하나만 있어야 하는 것이 아니다.
예를 들어, 다음과 같이 여러 개 사용할 수 있다.
import { useState } from "react";
function App() {
const [count, setCount] = useState(0);
const [name, setName] = useState("홍길동");
return (
<div>
<h1>{name}</h1>
<p>{count}</p>
<button onClick={() => setCount(count + 1)}>
숫자 증가
</button>
<button onClick={() => setName("김철수")}>
이름 변경
</button>
</div>
);
}
export default App;
Step 9. Props와 State의 차이
| 개념 | 의미 |
| Props | 부모가 전달해준 값 |
| State | 컴포넌트가 스스로 기억하는 값 |
예를 들어,
function Counter({ title }) {
const [count, setCount] = useState(0);
}
에서
- title → Props
- count → State
이다.
즉,
부모
│
│ props
↓
Counter
Counter 내부
│
└── state
라고 생각하며 된다.
Step 10. Props와 State 같이 사용해보기
import { useState } from "react";
function Counter({ title }) {
const [count, setCount] = useState(0);
function increase() {
setCount(count + 1);
}
return (
<div>
<h2>{title}</h2>
<p>{count}</p>
<button onClick={increase}>+1</button>
</div>
);
}
function App() {
return (
<div>
<Counter title="첫 번째 카운터" />
<Counter title="두 번째 카운터" />
</div>
);
}
export default App;
이 코드를 실행해보면 첫 번째 카운터의 버튼을 눌러도 두 번째 숫자는 변하지 않고 두 번째 카운터의 버튼을 눌러도 첫 번째 숫자는 변하지 않는다.
왜냐하면,
<Counter title="첫 번째 카운터" />
와
<Counter title="두 번째 카운터" />
이 두 컴포넌트는 각각 자신의 State를 가지고 있기 때문이다.
개념적으로는
Counter 1
count = 3
Counter 2
count = 0
처럼 따로 존재한다.
React에서 중요한 핵심 흐름
Event
↓
setState
↓
State 변경
↓
컴포넌트 다시 실행
↓
화면 업데이트'개발 > React' 카테고리의 다른 글
| [React] 조건부 렌더링과 리스트 렌더링 (0) | 2026.09.15 |
|---|---|
| [React] Input과 State (0) | 2026.09.15 |
| [React] Component와 Props (0) | 2026.09.14 |
| [React] React 개요 (0) | 2026.09.14 |
| [React] React를 위한 JavaScript (3) (0) | 2026.09.09 |