양식 상태 관리
상태로 필드 값을 보관하고 업데이트합니다.
양식 상태 관리은(는) CoddyKit의 무료 Android Academy 강의입니다. 이것은 4개 중 2번째 강의입니다. 아래에서 전체 강의를 무료로 읽을 수 있으며, 내장 코드 에디터와 24/7 AI 튜터와 함께 브라우저에서 직접 실습할 수 있습니다. 이 강의는 Android Academy 학습 경로의 일부이며, 진행 상황이 웹과 CoddyKit 앱에 동기화됩니다. Android Academy 강의에는 총 4개의 강의가 포함되어 있습니다.
한 필드에서 양식으로
텍스트 필드 하나는 간단합니다. 실제 양식에는 이름, 이메일, 비밀번호, 체크박스 등 여러 필드가 있습니다. 이 과정에서는 Jetpack Compose에서 전체 양식의 상태를 보관하고 업데이트하는 깔끔한 방법을 배웁니다.
이 방법을 제대로 익히면 유효성 검사, 제출, 미리 보기를 모두 간단하게 처리할 수 있습니다.
여러 개의 독립적인 상태
가장 간단한 방법은 필드마다 mutableStateOf를 하나씩 사용하는 것입니다. 각 필드가 자신의 상태를 읽고 업데이트합니다.
필드가 두세 개인 작은 양식에는 이 방법이 충분히 적합합니다.
@Composable
fun LoginForm() {
var email by remember { mutableStateOf("") }
var password by remember { mutableStateOf("") }
Column {
OutlinedTextField(email, { email = it }, label = { Text("Email") })
OutlinedTextField(password, { password = it }, label = { Text("Password") })
}
}데이터 클래스로 상태 묶기
양식이 커지면 흩어진 변수가 많아져 복잡해집니다. 더 깔끔한 방법은 전체 양식을 하나의 변경 불가능한 data class로 모델링하는 것입니다.
해당 객체를 담은 단일 상태를 유지하고 copy()로 업데이트합니다.
data class SignUpState(
val name: String = "",
val email: String = "",
val agreedToTerms: Boolean = false
)copy()로 업데이트하기
상태 객체는 변경할 수 없으므로 제자리에서 수정하지 않습니다. 대신 한 필드만 변경한 새 복사본을 만들어 다시 할당합니다.
이렇게 하면 Compose의 상태 모델을 예측 가능하게 유지할 수 있습니다. 새 객체는 새 스냅샷을 의미하고, 재구성을 촉발합니다.
var form by remember { mutableStateOf(SignUpState()) }
OutlinedTextField(
value = form.name,
onValueChange = { form = form.copy(name = it) },
label = { Text("Name") }
)전체 데이터 클래스 폼
여기서는 전체 폼이 하나의 SignUpState에 의해 관리됩니다. 각 필드는 copy()를 사용해 하나의 속성만 업데이트합니다.
언제든지 전체 폼의 값을 얼마나 쉽게 읽을 수 있는지 확인해 보세요. 단순히 form을 읽으면 됩니다.
var form by remember { mutableStateOf(SignUpState()) }
Column {
OutlinedTextField(
value = form.name,
onValueChange = { form = form.copy(name = it) },
label = { Text("Name") }
)
OutlinedTextField(
value = form.email,
onValueChange = { form = form.copy(email = it) },
label = { Text("Email") }
)
}체크박스와 스위치
모든 입력이 텍스트인 것은 아닙니다. Checkbox나 Switch도 불리언 값과 onCheckedChange 콜백을 사용하는 같은 방식으로 작동합니다.
문자열과 마찬가지로 불리언을 폼 상태에 저장하면 됩니다.
var form by remember { mutableStateOf(SignUpState()) }
Row(verticalAlignment = Alignment.CenterVertically) {
Checkbox(
checked = form.agreedToTerms,
onCheckedChange = { form = form.copy(agreedToTerms = it) }
)
Text("I agree to the terms")
}상태에서 값 도출하기
상태를 단일 출처로 관리할 때의 큰 장점 중 하나는 추가 변수를 저장하지 않고도 상태에서 값을 계산할 수 있다는 것입니다. 예를 들어 폼을 제출할 준비가 되었는지 계산할 수 있습니다.
derivedStateOf 또는 간단한 표현식을 사용하면 폼이 변경될 때 결과가 자동으로 업데이트됩니다.
var form by remember { mutableStateOf(SignUpState()) }
val canSubmit by remember {
derivedStateOf {
form.name.isNotBlank() &&
form.email.isNotBlank() &&
form.agreedToTerms
}
}
Button(onClick = { /* submit */ }, enabled = canSubmit) {
Text("Sign Up")
}구성 변경에도 상태 유지하기
remember는 재구성 중에 상태를 유지하지만 화면 회전과 같은 구성 변경이 발생하면 상태가 사라집니다. 회전 후에도 간단한 값을 유지하려면 rememberSaveable을 사용하세요.
기본형과 Parcelable 형식은 별도의 설정 없이 사용할 수 있습니다.
var email by rememberSaveable { mutableStateOf("") }
OutlinedTextField(
value = email,
onValueChange = { email = it },
label = { Text("Email") }
)폼 상태를 ViewModel로 끌어올리기
간단한 폼을 넘어서는 경우에는 상태를 ViewModel에 보관하세요. 구성 변경 후에도 상태가 유지되고 UI 로직을 컴포저블에서 분리할 수 있습니다.
컴포저블은 상태를 읽고 이벤트를 전달하며, 실제 상태의 원본은 ViewModel이 관리합니다.
class SignUpViewModel : ViewModel() {
var state by mutableStateOf(SignUpState())
private set
fun onNameChange(value: String) {
state = state.copy(name = value)
}
}ViewModel 연결하기
컴포저블에서 ViewModel을 가져온 다음 각 필드를 해당 상태 및 처리기에 연결하세요. UI는 얇게 유지되어 테스트하기 쉬워집니다.
이 구조는 실제 서비스의 폼에 권장되는 방식입니다.
@Composable
fun SignUpScreen(vm: SignUpViewModel = viewModel()) {
OutlinedTextField(
value = vm.state.name,
onValueChange = vm::onNameChange,
label = { Text("Name") }
)
}순수 Kotlin: copy() 동작 확인하기
copy() 업데이트 패턴은 표준 Kotlin 데이터 클래스 동작일 뿐입니다. 여기서는 각 업데이트가 완전히 새로운 객체를 만드는 과정을 볼 수 있도록 독립적으로 실행합니다.
data class SignUpState(
val name: String = "",
val email: String = ""
)
fun main() {
var state = SignUpState()
state = state.copy(name = "Ada")
state = state.copy(email = "ada@dev.io")
println(state)
}빠른 확인
상태에 저장된 변경 불가능한 data class로 폼을 모델링했습니다. 하나의 필드를 어떻게 업데이트해야 할까요?
복습
이제 전체 폼의 상태를 관리하는 방법을 배웠습니다.
- 작은 폼: 필드마다 하나의
mutableStateOf를 사용합니다. - 큰 폼: 하나의 변경 불가능한
data class를 사용하고copy()로 업데이트합니다. - 텍스트 필드를 텍스트로 관리하는 것처럼 불리언으로
Checkbox와Switch를 관리합니다. - "제출 가능 여부"와 같은 값은 저장하지 말고 도출합니다.
- 회전에는
rememberSaveable을 사용하고, 실제 화면에는ViewModel을 사용합니다.
다음: 입력을 검증하고 유용한 오류를 표시하는 방법입니다.
자주 묻는 질문
“양식 상태 관리” 강의는 무료인가요?
네 — “양식 상태 관리” 전체 내용을 이 웹사이트에서 무료로 읽을 수 있습니다. 인터랙티브하게 실습하려면(내장 코드 에디터와 24/7 AI 튜터), CoddyKit PRO로 업그레이드하면 Android Academy 강의 전체를 잠금 해제할 수 있습니다. Android Academy 강의에는 총 4개의 강의가 포함되어 있습니다.
“양식 상태 관리”에서 뭘 배우나요?
상태로 필드 값을 보관하고 업데이트합니다. 브라우저에서 직접 실행하는 실습 코드로 Android Academy을(를) 배우며, 24/7 AI 튜터가 강의를 진행하면서 질문에 답변해줍니다.
Android Academy을(를) 시작하는 데 경험이 필요한가요?
사전 경험은 필요하지 않습니다. CoddyKit의 Android Academy은(는) 초급자부터 고급 학습자까지를 위해 구성되어 있으므로, 여기서 시작하거나 처음부터 시작할 수 있으며 자신의 속도대로 진행할 수 있습니다. 이것은 4개 중 2번째 강의입니다.
“양식 상태 관리” 강의는 얼마나 걸리나요?
대부분의 CoddyKit 강의는 약 5~10분이 소요됩니다. 각 강의는 간결하고 인터랙티브하여 꾸준한 진행이 가능하며, 웹과 앱에서 중단한 부분부터 바로 시작할 수 있습니다.
이 Android Academy 강의에서 코드를 작성하고 실행할 수 있나요?
네. 모든 Android Academy 강의에는 내장 코드 에디터가 포함되어 있으므로, 브라우저에서 바로 실제 코드를 작성하고 실행한 후 즉시 AI 피드백을 받을 수 있습니다 — 로컬 설정이 필요 없습니다.