
derivedStateOf를 실무에서 종종 사용한 적이 있다.
최근에 사용했던 경험은 배송지를 등록하는 화면에서 조건에 맞을 때 다음 버튼이 활성화 되면 되는 작업이였다.
// AddAddressScreen.kt
val canGoNext by remember {
derivedStateOf {
uiModel.addressName.isNotEmpty && // 주소가 빈값이 아닌지
uiModel.regionCode.isNotEmpty && // 지역코드가 빈값이 아닌지
uiModel.addressName.length <= 5 && // 주소가 5글자 이내인지
}
}
라는 로직을 작성한 뒤 테스트 해보왔다. 근데 동작을 제대로 안헀다.
부끄럽게도 난 이유를 몰라서 찾아봤었다.
그래서 이참에 안됐던 이유와 함께 derivedStateOf를 알아볼려고 한다.
안됐던 이유는 부끄럽게도 remember에 key값을 안줬기때문이다. 현재 derivedStateOf 안에 값들은 uiModel로 이루어져있는 값들인데 state한 값들이 아니여서 자동으로 추적이 안됐기때문이다.
// AddAddressScreen.kt
val canGoNext by remember(uiModel) {
derivedStateOf {
uiModel.addressName.isNotEmpty && // 주소가 빈값이 아닌지
uiModel.regionCode.isNotEmpty && // 지역코드가 빈값이 아닌지
uiModel.addressName.length <= 5 && // 주소가 5글자 이내인지
}
}
그래서 이게 올바른 구현이다.
위에 로직에서 이상한 점을 눈치 못챘다면 당신은 제대로 이해하지 못하고 있는 것이다.. (나포함ㅠ)
최근에 사용했던 경험은 배송지를 등록하는 화면에서 조건에 맞을 때 다음 버튼이 활성화 되면 되는 작업이였다.
해당 조건을 만족시키기 위해서는 derivedStateOf를 굳이 사용할 필요가 없다.
다시말해 derivedStateOf를 사용해도 최적화 시키는데 전혀 도움이 안되고 있다는 소리다.
derivedStateOf는 state로부터 파생된 결과값을 만드는데 이때 state값이 빈번하게 변할 때 사용하는 것이 좋다.
예를 들자면
val addressTextFieldState = TextFieldState() // state한 값
val enableButton by remember(uiModel.regionCode) {
derivedStateOf {
addressTextFieldState.text.isNotEmpty && // 주소가 빈값이 아닌지
uiModel.regionCode.isNotEmpty && // 지역코드가 빈값이 아닌지
addressTextFieldState.text.length <= 5 && // 주소가 5글자 이내인지
}
}
이 경우이다. 주소를 입력할 때 초당 수차례 발생하는 걸 방지할 수 있다는 점에서 충분히 derivedStateOf를 잘쓰고있다고 생각한다.
그래서 내가 하고자 했던 로직은 사실 의미가 없는 것이고 사실
val canGoNext =
uiModel.addressName.isNotEmpty() &&
uiModel.regionCode.isNotEmpty() &&
uiModel.addressName.length <= 5
이렇게 사용하면 되는 것이다...!!
derivedStateOf는 텍스트필드나 스크롤값들처럼 빈번하게 변하는 state한 값들로부터 파생된 결과값을 도출할 때 제일 효율적으로 사용할 수 있는 것 같다.