[Jetpack Compose] remember 등이 가진 key 파라미터에 대해 알아보자

오규성·2025년 11월 6일

Jetpack Compose 기초

목록 보기
4/13

이번 시간에는 key 에 관하여 알아보려고 한다.
우선 key 에 대해 알아보기 앞서, 코드를 작성해보자.

class MainActivity() : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        setContent {
            enableEdgeToEdge()
            MaterialTheme {
                Scaffold {
                    var count by remember { mutableIntStateOf(1) }
                    val isEven = remember { count % 2 == 0 }

                    Column(modifier = Modifier
                        .fillMaxSize()
                        .padding(it)
                    ) {
                        Text(text = count.toString())
                        Button(
                            onClick = {
                                count++
                                Timber.d("${count}으로 변경 완료")
                            }
                        ) { Text(text = "숫자 올리기")}
                        Text(text = "짝수인가? - $isEven")
                    }
                }
            }
        }
    }
}

위의 코드에서는 아래 3가지 컴포저블이 존재한다.

  • count 를 보여주는 Text
  • count 를 증가시키는 버튼
  • 짝수인지 보여주는 Text

당연히 처음에는 초기화값대로 설정되어있을 것이다.
이제 버튼을 눌러 count 를 홀수로 만들어주고 텍스트를 살펴보자.

최초 false 였던 것이 여전히 false 로 유지되고 있다.

# 왜 변경되지 않는 걸까

이전에 remember 는 내부 계산을 저장한다고 알려준 적이 있다.
다시 한 번 remember 함수를 살펴보자.

@Composable
inline fun <T> remember(crossinline calculation: @DisallowComposableCalls () -> T): T =
    currentComposer.cache(false, calculation)
@ComposeCompilerApi
inline fun <T> Composer.cache(invalid: Boolean, block: @DisallowComposableCalls () -> T): T {
    @Suppress("UNCHECKED_CAST")
    return rememberedValue().let {
        if (invalid || it === Composer.Empty) {
            val value = block()
            updateRememberedValue(value)
            value
        } else it
    } as T
}

remember 함수는 key 를 지정해주지 않으면, invalid 가 false 로 지정되기 때문에 최초의 컴포지션이 아니면 재계산을 진행하지 않는다.
그렇기에 state 를 변경시켜주려면 currentComposer.cache()invalid 를 true 로 만들거나, 값을 직접 조정해주어야한다.

여기서 invalid 가 현재 말하는 key 이다.
즉, key 를 넣어주고, 리컴포지션 시 key 가 이전과 다르다면 계산식이 다시 실행되어 변수값이 변화할 수 있게 되는 것이다.

이제 key 를 지정해보자.

이제 이를 알았으므로, isEven 의 remember 에 key 를 지정해주자.
val isEven = remember(count) { count % 2 == 0 }.

  1. 버튼 클릭 시 count State 가 변경되면서 Scaffold 스코프가 리컴포지션
  2. count 가 변경되면서 isEven 도 변경
  3. 현재 isEven 과 이전에 등록된 isEven 과 equals 로 비교하고 false 면 UI 다시 그림

순으로 이어진다.

다만 위처럼 key 지정을 해주면 key 가 변경될때마다 계산식이 매번 이루어지므로 이를 참고하자.

key 가 State.value 일 필요는 없다.

이전 값과 같은지 판단을 하기 위해 존재하므로, State 나 State.value 일 필요는 없다.

class MainActivity() : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        setContent {
            enableEdgeToEdge()
            MaterialTheme {
                var count by remember { mutableIntStateOf(1) }
                val test = Random.nextInt()
                val isEven = remember(test) { count % 2 == 0 }

                Scaffold {
                    Column(modifier = Modifier
                        .fillMaxSize()
                        .padding(it)
                    ) {
                        Text(text = count.toString())
                        Button(
                            onClick = {
                                count++
                                Timber.d("${count}으로 변경 완료")
                            }
                        ) { Text(text = "숫자 올리기")}
                        Text(text = "짝수인가? - $isEven")
                    }
                }
            }
        }
    }
}

위 코드를 실행하면 버튼을 눌러 발생시키는 리컴포지션마다 isEven 이 바뀌는 것을 알 수 있다.
단, key 가 변경되었는지 판단은 리컴포지션 때 발생하므로 이것또한 참고하자.


Tistory 글을 옮기고 있는데, 예전 글 및 내 지식이 몇 가지 이상한 부분이 있었다는 것을 지금 알았다... 글들을 옮기면서 다시 공부하지 않았으면 큰일났을 것 같다.

profile
안드로이드 개발자 Gyu 의 개발 블로그 !

0개의 댓글