Jetpack Compose에서의 State란?
상태는 어떤 타입이든 될 수 있다. Int, Float, Double, Boolean, String, 여러 값을 포함한 data class 등
Jetpack Compose에서는 이 상태 값이 변경될 때마다 UI는 업데이트 된다.
Compose가 상태 변경을 인식하는 방법은 무엇일까?
@Composable
fun Somting() {
var check by remember { mutableStateOf(false) }
Text("Check is $check")
}
상태를 담는 객체를 사용해 값을 추적한다.
예를 들어 위와 같은 코드가 존재할 때, 하나씩 살펴보면 다음과 같다.
- by = kotlin delegates 키워드로써, 사용 시 객체 자체를 반환하는 것이 아니라 객체 내 타입 형태로 반환한다.
- remember{} = 컴포저블 함수가 재구성되더라도 람다 {}를 실행하지 않고, 전달값을 기억한다.
- mutableStateOf(false) = 상태에 대한 값을 보유할 객체를 반환한다.
만약 mutableStateOf()를 뺀다면?
@Composable
fun Somting() {
var check by remember { false }
Text("Check is $check")
}
- check를 true로 변경하더라도 UI는 인식하지 못하여 업데이트 되지 않습니다.
만약 remember()를 뺀다면?
@Composable
fun Somting() {
var check by mutableStateOf(false)
Text("Check is $check")
}
- UI가 상태 값이 변경되는 것을 인식하고 업데이트를 시도하지만, check 값은 기존에 초기화된 false 값만 기억하여 결과적으로 업데이트 되지 않습니다.
만약 by를 뺀다면?
@Composable
fun Somting() {
var check remember { mutableStateOf(false) }
Text("Check is $check")
}
- 평범하게 작동합니다. 하지만, 객체가 반환되기 때문에 값을 따로 빼주어야합니다. 위 코드를 예로 들면 Boolean 타입으로 빠져나오지 않고 mutableStateOf() 객체로 빠져나와 추가로 .value를 사용해 값을 얻어내야 합니다.
Stateless Composables
상태를 가지고 있지 않은 함수를 Stateless라고 한다. 대부분의 경우 Composable 함수를 Stateless하게 유지하고 싶어한다. 개발자가 현재 상황을 파악하고 테스트를 쉽게 하기 위함이다.
@Composable
fun StatelessButton(label: String, onClick: () -> Unit) {
Button(onClick) {
Text(label)
}
}
Stateless한 컴포저블이란 위와 같다. StatelessButton 함수는 호출자가 넘겨주는 label과 onClick 리스너에 의존하고 있으며, State를 가지고 있지 않다. 이것이 Stateless한 함수다.
이는 Jetpack Compose 튜토리얼에도 나오는 내용으로 공식에서 권장하고 있다고 볼 수 있다.
아래 링크의 맞춤 팁 계산, 자동 테스트 작성, 프로젝트: Art Space에 이어지기까지의 프로젝트 코드, 설명을 보면 Stateless한 함수를 절차적으로 생성하는 방법에 대해 설명해주고 있다.
Stateful Composables
스크린 레벨의 컴포저블 함수는 전체 화면의 상태를 유지하기에 적합하다. 일반적으로 이런 컴포저블이 화면 전체의 상태를 계산하는 ViewModel을 참조하고 있기에 새로운 상태가 발행되더라도 필요한 값들을 하위 객체로 전달할 수 있다.
@Composable
fun HomeScreen() {
val homViewModel = vewModel { HomeScreenViewModel() }
val state by homViewModel.inputText
}
State Hoisting
컴포저블 함수가 상태를 가지고 있지 않도록 없애는 것을 의미하는 것으로 상태 대신 함수 파라미터로 상태를 전달한다.
@Composable
fun StatefulCounter() {
var count by remember { mutableStateOf(0) }
Button(onClick = { count++ }) {
Text("Clicked $count times")
}
}
↓
@Composable
fun StatelessCounter(count: Int, onClick : ()->Unit){
Button(onClick = onClick) {
Text("Clicked $count times")
}
}
Jetpack Compose를 공부하면서 너무나도 많은 변화에 솔직히 혼란스럽다.
아직 제대로 이해하지 못했음에도 제대로 다룰 수만 있다면 기존에 작성하던 코드에 비해 최적화가 많이 될 것 같고 복잡하게 꼬아서 연결시키지 않아도 될 것 같다는 생각이 든다.
'개발 > AOS' 카테고리의 다른 글
Scaffold와 LazyColumn (1) | 2024.05.03 |
---|---|
Jetpack Compose 커스텀 그림자 (0) | 2024.05.02 |
Firebase - 구글 로그인 연동 / 이메일 회원가입 (0) | 2024.02.02 |
UI 공부 (0) | 2024.01.16 |
날씨 앱 기록 03 (1) | 2023.10.20 |
포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!