
React – 상태 관리와 Hooks – State와 Props – 3 – 상태 끌어올리기 패턴
안녕하세요, 리액트를 함께 배우고 있는 여러분! 😊
오늘은 React 개발에서 공통적으로 데이터를 관리해야 할 때 자주 등장하는 핵심 개념, 바로 “상태 끌어올리기(Lifting State Up)” 패턴에 대해 자세히 설명드릴게요.
이 개념은 마치 가족끼리 쓰는 리모컨을 하나로 정리하는 것과 비슷해요.
각 방마다 다른 리모컨이 있으면 헷갈리잖아요? 상태도 마찬가지예요. 여러 자식 컴포넌트에서 같은 데이터를 쓰고 바꿔야 한다면, 중앙에 하나로 묶어서 관리하는 게 깔끔하고 효율적이랍니다!
1. 상태 끌어올리기가 필요한 상황
자식 컴포넌트 여러 개가 같은 데이터를 참조하거나 수정할 필요가 있을 때,
각 자식에서 따로 상태를 관리하면 동기화가 깨지고 버그가 발생할 수 있어요.
그래서 이럴 땐 부모 컴포넌트로 상태를 끌어올려서 한 곳에서 관리하고,
각 자식은 props로 상태와 변경 함수를 받아서 사용하게 됩니다.
2. 예시 상황: 두 입력값을 비교해야 할 때
❌ 상태를 자식이 각각 가질 경우
function TemperatureInput() {
const [temp, setTemp] = useState('');
return <input value={temp} onChange={e => setTemp(e.target.value)} />;
}
function Calculator() {
return (
<>
<TemperatureInput />
<TemperatureInput />
</>
);
}
- 두 컴포넌트는 각각 다른 state를 갖고 있어서 서로 연동되지 않아요.
- 이때는 상태를 부모
Calculator
로 끌어올려야 합니다.
3. ✅ 상태 끌어올리기 적용 예시
function TemperatureInput({ label, temperature, onTemperatureChange }) {
return (
<div>
<label>{label}</label>
<input
value={temperature}
onChange={e => onTemperatureChange(e.target.value)}
/>
</div>
);
}
function Calculator() {
const [temperature, setTemperature] = useState('');
return (
<>
<TemperatureInput
label="섭씨"
temperature={temperature}
onTemperatureChange={setTemperature}
/>
<TemperatureInput
label="화씨"
temperature={temperature}
onTemperatureChange={setTemperature}
/>
</>
);
}
👉 흐름 정리
Calculator
가 상태의 소유자- 두 자식 컴포넌트는 같은 값을
props
로 받고, - 입력을 변경하면 부모의 상태(
setTemperature
)가 갱신됨 - 결국 두 입력창이 동일한 값을 공유하게 됨
4. 상태 끌어올리기의 일반적인 절차
- 공통으로 필요한 데이터를 찾는다.
- 그 데이터를 부모 컴포넌트로 끌어올려서 useState로 선언한다.
- 그 값을 자식 컴포넌트에 props로 전달한다.
- 자식 컴포넌트가 데이터를 바꿔야 한다면, 변경 함수도 props로 전달한다.
5. 또 다른 예시: 체크박스 동기화
function ChildCheckbox({ label, checked, onToggle }) {
return (
<label>
<input type="checkbox" checked={checked} onChange={onToggle} />
{label}
</label>
);
}
function Parent() {
const [isChecked, setIsChecked] = useState(false);
return (
<>
<ChildCheckbox
label="옵션 A"
checked={isChecked}
onToggle={() => setIsChecked(prev => !prev)}
/>
<ChildCheckbox
label="옵션 B"
checked={isChecked}
onToggle={() => setIsChecked(prev => !prev)}
/>
</>
);
}
➡️ 이처럼 하나의 상태를 공유해서 두 체크박스가 동시에 체크/해제되도록 만들 수 있어요.
6. 상태 끌어올리기의 장점
장점 | 설명 |
---|---|
데이터 일관성 유지 | 여러 자식이 같은 상태를 사용할 때 버그 방지 |
유지보수 용이 | 상태 위치를 한눈에 파악 가능 |
테스트 용이성 ↑ | 상태 추적과 흐름 분석이 쉬움 |
재사용성 향상 | Dumb 컴포넌트화하여 다양한 상황에 활용 가능 |
7. 상태 끌어올릴 때 주의할 점
항목 | 설명 |
---|---|
상태 위치 과도하게 끌어올리지 않기 | 너무 상위로 올리면 컴포넌트 간 결합도 증가 |
props 전달이 복잡해질 수 있음 | 중첩이 깊을 경우 Context 사용 고려 |
자식 컴포넌트는 상태를 변경하지 말고 | 반드시 props로 받은 콜백 함수만 사용해야 함 |
8. 실전에서 자주 쓰이는 상황 예
- 입력 폼에서 여러 필드 상태를 한 부모에서 관리할 때
- 검색 필터처럼 여러 컴포넌트가 동일한 필터 기준을 공유할 때
- 다중 선택 UI에서 모든 선택 항목을 부모에서 제어할 때
- 동기화된 UI (예: 슬라이더와 숫자 입력창)
9. 비슷한 개념: Controlled vs Uncontrolled
구분 | 설명 |
---|---|
Controlled | 상태를 부모에서 제어 (React 권장 방식) |
Uncontrolled | 상태를 DOM에서 직접 관리 (ref 사용) |
➡️ 상태 끌어올리기는 Controlled 컴포넌트 전략의 연장선이에요!
10. 마무리하며
상태 끌어올리기는 React에서 복잡한 UI를 유기적으로 구성할 수 있는 핵심 패턴입니다.
각 자식이 제각각 데이터를 관리하기보단, 공통의 상위 부모가 중심을 잡고 흐름을 컨트롤하는 구조를 만드는 게 훨씬 안정적이에요.
이 구조를 잘 익혀두면 다음 단계에서 배우게 될 Context API나 전역 상태 관리 도구(Redux, Recoil 등) 도 더욱 쉽게 이해할 수 있답니다!
📌 한 문장으로 정리하면:
“여러 자식이 같은 데이터를 사용한다면, 상태는 그들의 공통 부모에 있어야 한다!”
다음 글에서는 이 흐름 위에서 효율적인 데이터 처리와 최적화 방법을 다뤄보겠습니다. 함께 꾸준히 배워가요! 🚀