id, title, category, status, source_trust_level, verification_status, created_at, updated_at, tags, tech_stack, applied_in, aliases
| id |
title |
category |
status |
source_trust_level |
verification_status |
created_at |
updated_at |
tags |
tech_stack |
applied_in |
aliases |
| android-compose-state-hoisting |
Jetpack Compose — State Hoisting |
Coding |
draft |
B |
conceptual |
2026-05-09 |
2026-05-09 |
| android |
| compose |
| state-hoisting |
| vibe-coding |
|
| language |
applicable_to |
| Kotlin / Jetpack Compose |
|
|
|
| stateful |
| stateless |
| controlled composable |
|
Compose State Hoisting
Composable 은 가능한 stateless. state 는 호출자가 보유, (value, onValueChange) 한 쌍 으로 주입. 테스트 / 재사용 / preview 모두 쉬워짐. React 의 controlled component 와 같은 철학.
📖 핵심 개념
- Stateful: 자기 안에
remember { mutableStateOf(...) } 보유.
- Stateless: state 를 외부에서 받음. 같은 입력 = 같은 UI.
- Hoist: state 를 가장 가까운 공통 부모로 끌어올림.
💻 코드 패턴
Stateless + 호출자 hoist
두 컴포저블이 같은 state 공유 → 부모로 hoist
rememberSaveable — config change 에 보존
복잡 state — Holder 패턴
🤔 의사결정 기준
| 상황 |
패턴 |
| 한 composable 내부 UI state (toggle 펼침 등) |
remember { mutableStateOf } |
| 두 형제가 같은 state |
부모로 hoist |
| screen 단위 비즈니스 state |
ViewModel + StateFlow |
| 화면 회전 보존 |
rememberSaveable |
| 여러 필드 + 검증 |
State Holder 클래스 |
❌ 안티패턴
- 모든 state 를 ViewModel 까지 끌어올림: 작은 toggle 도 viewmodel 행. 가까운 공통 부모로.
- stateful + props 동시 보유 (
var x by remember(...) + prop x): 어느 게 진실?. 한쪽으로.
MutableState 를 직접 외부 노출: 캡슐화 깨짐. State 만 노출.
- rememberSaveable 안에 너무 큰 객체: Bundle 한계 / TransactionTooLarge crash.
- Composable 안에서
LaunchedEffect 없이 launch: lifecycle 관리 안 됨.
- derivedStateOf 안 쓰고 매번 계산: 불필요 recomposition.
🤖 LLM 활용 힌트
- "이 state 가 누구의 것인가? 가장 가까운 공통 부모는?" 매 composable 작성 시 점검.
- ViewModel 은 비즈니스 state, composable 은 UI-local state 만.
🔗 관련 문서