코틀린 & 컴포즈 & Java/컴포즈 Compose

[Compose] Compose에서 key의 역할과 사용법

코딩하는후운 2025. 2. 6. 17:21
반응형

Compose에서 key의 역할과 사용법

Compose에서 key 컴포저블의 상태 유지 및 무효화 관리를 위한 중요한 개념입니다.
이를 올바르게 사용하면 
효율적인 상태 관리와 UI 업데이트를 구현할 수 있습니다. 

 

key의 역할과 사용하는 이유

📌 key의 역할

  • Compose의 재구성(Recomposition) 로직을 제어합니다.
  • 특정 값이 변경될 때 기존 상태를 무효화하고 새로운 상태를 초기화할 수 있습니다.

📌 key가 상태에 미치는 영향 (상태 소멸 조건)

  • key 값이 변경되면 기존 상태가 무효화되고 새로운 상태가 생성됩니다.
  • 새로운 객체가 생성되므로, 기존에 저장된 상태는 유지되지 않습니다.
@Composable
fun CounterWithKey(userId: String) {
    var count by remember(key(userId)) { mutableStateOf(0) }

    Column {
        Text("User: $userId")
        Button(onClick = { count++ }) {
            Text("Count: $count")
        }
    }
}

📌 동작 방식:

  • userId가 변경될 때마다 count의 상태가 초기화됩니다.
  • key(userId)를 사용하면, 특정 값이 바뀔 때 새로운 상태를 생성하도록 제어할 수 있습니다.

 

key를 사용하여 상태 무효화

key를 활용해 특정 값이 변경될 때마다 새로운 객체를 생성하는 방식을 보여줍니다.

var key by remember { mutableStateOf(false) }
val date by remember(key) { mutableStateOf(Date()) }

Column {
    Text(date.toString())
    Button(onClick = { key = !key }) {
        Text("Click")
    }
}

📌 동작 방식:

  • key 값이 변경되면, 기존 date 상태가 무효화되고 새로운 Date 객체가 생성됩니다.
  • 이를 통해 특정 이벤트(예: 버튼 클릭)에 따라 상태를 새로 만들 수 있습니다.
 

key를 활용한 리스트 항목 식별

📌 LazyColumn에서 key 사용 예제

LazyColumn {
    items(listOf("A", "B", "A"), key = { System.identityHashCode(it) }) { item ->
        Text(item) // 각 항목을 고유하게 처리
    }
}

📌 이 코드에서 key의 역할:

  • 동일한 항목(예: "A")이 여러 개 있어도 각 항목을 고유하게 식별하여 잘못된 재구성을 방지합니다.
  • 마치 RecyclerView의 getItemId()와 유사한 역할을 수행합니다.

 

나의 LazyColumn 경험

나는 서버에서 key값에 넣은 id가 중복되게 내려온적이 있어 앱이 죽었다.

그래서 System.identityHashCode(it)객체의 메모리 주소 기반이므로 중복 방지를 하였습니다.

나는 Paging3 을 사용 했는데, Paging 3에서 LazyColumn은 자동으로 고유한 key를 관리한다고 한다.

📌 이 경우, Paging 3의 내부 구현에서 이미 각 아이템을 고유하게 관리하고 있으므로, 별도로 key를 설정할 필요가 없다.
Paging3는 자동으로 key를 할당하며, 각 페이지가 로드될 때 기존 데이터가 갱신됨.
✔ 따라서 LazyColumn의 key를 설정해도 PagingDataAdapter 내부에서 관리되므로 큰 효과가 없음.

 

key를 사용하는 주요 상황

1️⃣ 리스트 항목을 고유하게 식별

  • RecyclerView의 getItemId()와 같은 역할을 수행합니다.
  • LazyColumn, LazyRow 등에서 동일한 항목이 중복될 때 정확한 UI 업데이트를 보장합니다.

2️⃣ 상태 재생성 유도

  • 특정 값이 변경될 때, 이전 상태를 무효화하고 새 상태를 생성하고 싶을 때 사용합니다.

3️⃣ 조건에 따라 상태를 독립적으로 관리

  • 동일한 UI 컴포저블에서 특정 키에 따라 독립적인 상태를 관리해야 할 때 유용합니다.

 

Compose의 상태와 무효화 원리

Jetpack Compose는 효율적인 상태 관리를 위해 무효화 및 상태 생성 방식을 활용합니다.

📌 1. 무효화된 상태

  • 무효화된 상태는 더 이상 Compose 트리에서 사용되지 않으며, 참조에서 제외됩니다.
  • 가비지 컬렉션이 이를 제거할 수 있습니다.

📌 2. 새로운 상태

  • 무효화된 상태를 대체하기 위해 새로운 상태 객체가 생성됩니다.
  • 새로운 메모리 주소가 할당되며, Compose 트리에 연결됩니다.

📌 3. 효율성 보장

  • 무효화 및 상태 생성은 변경된 부분만 다시 생성하며, 나머지 Compose 트리는 그대로 유지합니다.
  • 이를 통해 최적화된 상태 업데이트가 이루어집니다.

 

Compose의 메모리 관리

  • Compose는 변경된 부분만 다시 생성하며, 이전 상태는 메모리에서 제거될 수 있도록 관리합니다.
  • 이 덕분에 상태 변경과 UI 재구성이 최대한 효율적으로 처리됩니다.

 

정리

key를 사용하면 특정 값이 변경될 때 상태를 초기화할 수 있으며, 리스트에서 고유한 항목을 관리할 수도 있습니다.
Compose의 상태 무효화 및 재구성 원리를 이해하고 활용하면, 보다 최적화된 UI를 구현할 수 있습니다. 🚀🔥

반응형