언제 derivedStateOf를 써야할까?

강현석·2023년 2월 8일
2

article

목록 보기
3/9
post-thumbnail

본 내용은 학습을 위해 Jetpack Compose — When should I use derivedStateOf? 을 보고 입맛대로 정리한 글입니다.


예시

사용자 이름이 알파벳인 경우, 버튼 활성화

var username by remember { mutableStateOf("") }
val submitEnabled = isUsernameValid(username)


"u"를 입력했는데 버튼 활성화



하지만, 이미 버튼이 활성화가 되었음에도 불구하고, 불필요하게 버튼에 state를 게속 보내고 있음


var username by remember { mutableStateOf("") }
val submitEnabled = remember {
	derivedStateOf { isUsernameValid(username) }


이 때, derivedStateOf를 사용하면, 불필요하게 버튼에 state를 보내지 않음
유효하지 않게 되면, 버튼에 state를 보냄

언제 사용하면 좋을까?

  • 스크롤이 경계값을 통과하는지 (scrollPosition > 0)
  • 리스트의 항목이 임계값보다 큰지 (아이템 > 0)
  • 위와 같은 유효성 검사 (username.isValid())

자주 묻는 질문

derivedStateOf를 remember?

  • composable 함수 안에서는 사용해야 함
  • derivedStateOfmutableStateOf 와 같이, recomposition이 일어나도 살아남아야 함
  • remember하지 않으면, recomposition할 때마다 매번 재할당됨

remember(key)와 derivedStateOf의 차이?

val result = remember(state1, state2) { calculation(state1, state2) }
val result1 = remember { derivedStateOf { calculation(state1, state2) } }
  • recomposition의 횟수 차이
  • remember(key)는 key가 변경되는 만큼 업데이트가 되어야 하는 경우
    • key마다 다른 값 remember

remember(key)와 derivedStateOf를 함께 사용? 언제 필요?

@Composable
fun ScrollToTopButton(lazyListState: LazyListState, threshold: Int) {
	// 버그 있음
  	val isEnabled by remember {
    	derivedStateOf { lazyListState.firstVisibleItemIndex > threshold }
  	}
  
  	Button(onClick = { }, enabled = isEnabled) {
    	Text("Scroll to top")
  	}
}
  • 처음(threshold가 0인 경우)에는 잘 동작함

  • 하지만 threshold가 변경되면, 조건(scrollPosition > threshold)이 맞지 않더라도 이전 값이 설정됨

  • threshold를 remember하게 되면, 변경할 때마다 state가 초기화됨

val isEnabled by remember(threshold) {
	derivedStateOf { lazyListState.firstVisibleItemIndex > threshold }
}

여러 state를 함께 결합하려면 derivedStateOf를 써야하나?

var firstName by remember { mutableStateOf("") }
var lastName by remember { mutableStateOf("") }

val fullName = remember { derivedStateOf { "$firstName $lastName" } }
  • input만큼 변경되기 때문에, derivedStateOf는 아무 작업도 수행하지 않고, 약간의 오버헤드만 발생시킴
  • 당연한 이야기이지만, derivedStateOf는 비동기 업데이트를 지원하지 않음
  • 즉, 필요하지 않음

결론

derivedStateOf {}는 UI를 업데이트하려는 것보다 state 또는 key가 더 많이 변경될 때 사용해야 함

profile
볼링을 좋아하는 안드로이드 개발자

1개의 댓글

comment-user-thumbnail
2023년 10월 17일

좋은 글 감사합니다

답글 달기