remember의 사용과 한계점
Composable에서 remember은 Recomposition이 일어날 때 상태를 관리하기 위해 사용된다. remember의 상태는 remember의 value를 직접 수정해주는 것으로만 가능하다.
@Composable
private fun TextFieldExample() {
val text = remember { mutableStateOf("Kotlin World") }
Column(modifier = Modifier.padding(16.dp)) {
OutlinedTextField(
value = text.value,
onValueChange = { text.value = it }
)
}
}
remember { mutableStateOf(...) }는 Composable이 처음 호출될 때 단 한 번만 실행되고, 이후 Recomposition이 일어나도 처음 remember된 값을 그대로 유지한다.
즉, 이후 외부 값(Input)이 바뀌어도 무시하고 이전 값을 계속 유지한다는 의미이다.
그래서 상태를 바꾸려면 value를 직접 수정해야 하는 방법 밖에 없다.
많은 사람들이 Composable의 상위 Composable에서 remember에 값을 주입해줘서 값이 업데이트 되지 않는 현상을 접한다.
예를 들어 아래의 코드를 살펴보자. 상위 Comopsable에서 text를 remember한 후 하위 Composable인 TextData에 넣어주고 있다.
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
var text by remember { mutableStateOf("zzz") }
Column(modifier = Modifier.padding(16.dp)) {
OutlinedTextField(
value = text,
onValueChange = { text = it }
)
TextData(input = text)
}
}
}
}
@Composable
private fun TextData(input: String) {
val rememberedInput by remember { mutableStateOf(input) }
Text(" rememberedInput: $rememberedInput")
}
하지만 이 코드를 실행해보면 데이터가 바뀌지 않는 것을 확인할 수 있다.

왜냐하면 이미 TextData Composable에서는 "zzz"로 remember된 rememberedInput이 있고 다시 초기화가 일어나지 않기 때문이다. rememberedInput을 수정하기 위해서는 rememberedInput의 value값을 직접 수정해줘야 한다.
이를 해결하기 위한 방법은 상위에서 데이터를 받았을 때 다음과 같이 value값을 직접 수정해주는 것이다.
@Composable
private fun TextData(input: String) {
val rememberedInput by remember { mutableStateOf(input) }.apply{
value = input
}
Text(" rememberedInput: $rememberedInput")
}
위와 같이 작업하면 TextData로 들어오는 input이 바뀌었을 때 rememberedInput의 value 값이 바뀌게 되어 TextData의 Recomposition이 일어난다.

rememberUpdatedState
위의 그림2와 같은 작업이 가능해주도록 하는 것이 바로 rememberUpdatedState이다.
rememberUpdatedState는 값이 들어올 때마다 새로운 value값을 remember된 mutableState에 직접 apply 해준다.
@Composable
fun <T> rememberUpdatedState(newValue: T): State<T> = remember {
mutableStateOf(newValue)
}.apply { value = newValue }
따라서 상위의 Composable의 데이터가 바뀔 때 하위 Composable의 remember된 데이터도 바뀌어야 한다면 rememberUpdatedState를 사용해야 한다.
remember과 rememberUpdatedState 차이 예시
이 둘의 차이는 다음의 코드를 통해 확인할 수 있다.
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
var text by remember { mutableStateOf("zzz") }
Column(modifier = Modifier.padding(16.dp)) {
OutlinedTextField(
value = text,
onValueChange = { text = it }
)
TextData(input = text)
}
}
}
}
@Composable
private fun TextData(input: String) {
val rememberedInput by remember { mutableStateOf(input) }
val rememberedUpdatedInput by rememberUpdatedState(input)
Text(" rememberedInput: $rememberedInput")
Text(" rememberedUpdatedStateInput: ${rememberedUpdatedInput}")
}
위 코드를 수행하면 다음의 결과가 나온다.

rememberUpdatedState 말고 remember(key) 를 사용하면 안되는 건가요?
remember 는 value 를 캐싱하며, value가 바뀔 때마다 새롭게 재계산을 하기 위해 아래와 같이 정의할 수 있다.
val test = remember(value) { mutableStateOf(value) }
하지만, 위와 같이 설정을 해줘야 참조한 상태에 따라 새로운 값으로 바뀌며, 이는 코드가 너무 긴 문제가 있다.
그래서 우리는 rememberUpdatedState 를 사용하여 이 코드를 많이 축소화할 수 있다.
그러나, rememberUpdateState를 완벽하게 대체하여 사용할 수 없는 문제가 있다.
일반적으로 rememberUpdateState는 LaunchedEffect나 DisposableEffect에서 자주 사용되는데, 예시를 통해 rememberUpdateState와 remember(key)의 차이점을 알아보자.
@Composable
fun TestComposable(){
var newNumber by remember { mutableIntStateOf (1000) }
Button(onClick = { newNumber++ }){}
RememberUpdatedStateTest(number = newNumber)
}
@Composable
fun RememberUpdatedStateTest(number: Int){
val rememberUpdatedStateValue by rememberUpdatedState(number)
LaunchedEffect(Unit) {
while (true){
delay(300L)
Log.e("숫자는 - ", rememberUpdatedStateValue.toString())
}
}
}
위와 같이 rememberUpdateState 를 사용한다면 Lambda 가 캡쳐한 값의 value 가 업데이트 되므로 Lambda 에서도 상태 업데이트를 확인할 수 있다.
하지만, rememberUpdateState를 다음과 같이 remember(Key)로 바꾼다면 결과에 어떤 영향을 미칠까?
@Composable
fun RememberUpdatedStateTest(number: Int){
val rememberValue by remember(number)
LaunchedEffect(Unit) {
while (true){
delay(300L)
Log.e("숫자는 - ", rememberValue.toString())
}
}
}
필자도 처음에는 remember(key){ mutableStateOf(value) } 로 선언해도 동일하게 동작할까 싶었지만, 직접 실험해보니 이것은 Lambda 에 제대로 값 전달이 안되었다.
이유는 다음과 같다.
- Lambda 의 변수 캡쳐는 final 로 전달되기에 상태 객체의 값이 변하여 새로운 객체로 갱신된다고 하더라도 Lambda 는 기존 객체 (주소) 를 바라보고 있다
- rememberUpdatedState 의 경우 apply { value = newValue } 를 사용하므로 새로운 객체로 변경하는 것이 아닌, 값만을 갱신하기에 객체 자체는 변함이 없다
- remember(key){ mutableStateOf(value) } 의 경우 내부 값이 달라진다면 새로운 State 객체를 생성하기 때문에 Lambda 에서 캡쳐한 객체와 아예 다른 객체가 되어버리기 때문에 Lambda 내부에서는 업데이트를 알 수 없게 된다.
이러한 기능을 가지고 있으니 RememberUpdatedState 는 람다를 사용할때 이용하면 좋다.
끝.
참고자료
[Compose State] remember과 rememberUpdatedState를 사용한 상태 관리
remember의 사용과 한계점 Composable에서 remember은 Recomposition이 일어날 때 상태를 관리하기 위해 사용된다.remember의 상태는 remember의 value를 직접 수정해주는 것으로만 가능하다. *by 키워드는 value에
kotlinworld.com
[Jetpack Compose] rememberUpdatedState 가 무엇인지 알아보자
rememberUpdatedState 가 무엇일까?remember 는 value 를 캐싱한다.하지만 value 가 바뀔때마다 새롭게 재계산을 하기 위해서는 key 를 설정해주어야한다.즉 아래와 같이 설정을 해줘야 참조한 상태에 따라
dev-gyu.tistory.com
'Android > Compose' 카테고리의 다른 글
[Android] Compose의 Layout 기초 (0) | 2025.05.16 |
---|---|
[Android] Compose의 CompositionLocal 이란? (0) | 2025.05.14 |
[Android] Compose의 부수효과(SideEffect) (0) | 2025.03.09 |
[Android] Compose 상태 호이스팅 위치 정하기 (0) | 2025.03.07 |
[Android] Compose 상태관리 (0) | 2025.03.07 |