React 상태 관리와 입력 반응 정리
React를 학습하면서 가장 중요한 개념 중 하나는 상태(state) 관리다. 특히 사용자 입력에 반응하는 방식과 상태를 다루는 방법을 이해하는 것이 중요하다. 이번 글에서는 React 공식 문서와 Reacting to Input with State를 기반으로, 상태 관리와 입력 반응에 대해 정리해보겠다.
1. React의 상태(state)란?
상태(state) 는 React 컴포넌트에서 값이 변경될 때 UI를 다시 렌더링하는 중요한 데이터다. 컴포넌트의 내부 상태를 나타내며, 예를 들어 사용자 입력, 체크박스 상태, 카운터 값 등이 상태가 될 수 있다.
React에서는 useState 훅을 사용해 상태를 관리한다.
useState를 이용한 상태 선언
import { useState } from "react";
function Counter() {
const [count, setCount] = useState(0);
return (
<div>
<p>현재 카운트: {count}</p>
<button onClick={() => setCount(count + 1)}>증가</button>
</div>
);
}
- useState(0): 초기 상태를 0으로 설정
- setCount(count + 1): 상태를 업데이트하면 React는 다시 렌더링
2. 상태의 유지와 초기화
React에서는 컴포넌트가 다시 렌더링될 때 상태가 유지된다. 하지만 컴포넌트가 언마운트되고 다시 마운트되면 상태가 초기화된다.
상태가 유지되는 이유
React는 컴포넌트가 같은 위치에 존재하는 한 상태를 유지한다. 하지만 다른 컴포넌트로 교체되거나, 리스트에서 제거되면 상태는 초기화된다.
function App() {
const [show, setShow] = useState(true);
return (
<div>
<button onClick={() => setShow(!show)}>토글</button>
{show && <Counter />}
</div>
);
}
- show가 false가 되면 <Counter />가 언마운트됨 → 다시 마운트될 때 초기 상태(count = 0)로 돌아감
3. React에서 입력값을 상태로 관리하기
사용자가 입력한 값을 즉시 반영하려면 useState를 사용해 입력 필드의 상태를 관리해야 한다.
입력값 상태 관리
import { useState } from "react";
function InputField() {
const [text, setText] = useState("");
return (
<div>
<input
type="text"
value={text}
onChange={(e) => setText(e.target.value)}
/>
<p>입력한 값: {text}</p>
</div>
);
}
- value={text}: 입력값을 상태와 연결
- onChange={(e) => setText(e.target.value)}: 입력 변경 시 상태 업데이트
4. 여러 개의 상태 관리하기
여러 개의 입력값을 한꺼번에 관리해야 하는 경우, useState를 객체 형태로 사용할 수 있다.
여러 개의 상태를 객체로 관리하기
import { useState } from "react";
function Form() {
const [formData, setFormData] = useState({ name: "", email: "" });
function handleChange(e) {
setFormData({
...formData,
[e.target.name]: e.target.value,
});
}
return (
<div>
<input
type="text"
name="name"
value={formData.name}
onChange={handleChange}
placeholder="이름"
/>
<input
type="email"
name="email"
value={formData.email}
onChange={handleChange}
placeholder="이메일"
/>
<p>이름: {formData.name}</p>
<p>이메일: {formData.email}</p>
</div>
);
}
- setFormData({...formData, [e.target.name]: e.target.value})
- 기존 상태를 유지하면서 변경된 필드만 업데이트
5. 상태 업데이트의 비동기성
React에서 setState 함수는 비동기적으로 동작한다. 즉, setState를 호출한 직후에는 상태가 즉시 업데이트되지 않는다.
function Counter() {
const [count, setCount] = useState(0);
function handleClick() {
setCount(count + 1);
console.log(count); // 이전 값이 출력됨
}
return <button onClick={handleClick}>클릭: {count}</button>;
}
이유는 React가 여러 개의 상태 업데이트를 한꺼번에 처리하기 위해 배치(batch) 업데이트를 수행하기 때문이다.
이 문제를 해결하려면 setState에 함수형 업데이트를 사용한다.
함수형 업데이트 사용하기
function Counter() {
const [count, setCount] = useState(0);
function handleClick() {
setCount((prevCount) => prevCount + 1);
}
return <button onClick={handleClick}>클릭: {count}</button>;
}
- setCount((prevCount) => prevCount + 1): 이전 상태 값을 안전하게 가져와 업데이트
6. 상태가 필요한 경우 vs 불필요한 경우
상태가 필요한 경우
- 사용자의 입력값을 추적할 때
- 네트워크 요청 후 데이터를 유지할 때
- 버튼 클릭 횟수를 기록할 때
- UI 요소의 가시성을 토글할 때
상태가 불필요한 경우
- 단순히 props를 통해 데이터를 전달받을 때
- 컴포넌트가 자체적으로 데이터를 수정하지 않고 화면에 표시만 할 때
function Greeting({ name }) {
return <p>안녕하세요, {name}님!</p>;
}
이처럼 props로만 데이터를 전달하는 경우 상태를 사용할 필요가 없다.
7. React의 상태 관리 패턴
React에서 상태를 효율적으로 관리하기 위해 몇 가지 패턴을 사용할 수 있다.
1) 리프팅 상태 올리기 (Lifting State Up)
여러 컴포넌트가 같은 데이터를 공유해야 할 때, 부모 컴포넌트에서 상태를 관리하는 방식.
2) 전역 상태 관리 (Context API, Redux 등)
앱 전체에서 공통으로 사용하는 상태(예: 다크 모드, 로그인 정보 등)는 Context API나 Redux 같은 전역 상태 관리 라이브러리를 사용한다.
8. 마무리
React에서 상태 관리는 컴포넌트 기반 UI의 핵심 요소다. 상태가 언제 필요한지, 어떻게 업데이트해야 하는지를 이해하면 더 효율적으로 React 애플리케이션을 개발할 수 있다.
이번 글에서는 useState를 이용한 기본 상태 관리, 입력값을 상태로 관리하는 방법, 상태 업데이트의 비동기성, 그리고 상태 관리 패턴까지 살펴보았다. 다음에는 useEffect를 활용한 상태 변경 반응과 최적화 기법도 정리해볼 예정이다.
오늘도 즐코 빡코 !!