Onii-Chan
Onii-Chan

Reputation: 1

What is the job of remember keyword in jetpack compose

I want selectedProvince to be persist so i put it in remember, but whenever i change value in onClick, the framework recomposes and the variable is set to be listProvince.value[0] again (only for the first time). I thought it would be the last selected value.

@Composable
fun ProvinceDialog(
    modifier: Modifier = Modifier,
    listProvince: MutableState<List<ProvinceItem>>,
    onDisMiss: () -> Unit = {},
    onConfirm: (String) -> Unit = {}
) {
    val searchText = remember { mutableStateOf("") }
    var selectedProvince = remember { mutableStateOf(listProvince.value[0]) }
    Log.d("Test select", selectedProvince.toString())

    AlertDialog(
        modifier = modifier,
        title = {
            Text(text = "Province")
        },
        containerColor = EDSColors.white,
        text = {
            Column(
                modifier = Modifier
                    .fillMaxSize()
                    .padding(16.dp),
                verticalArrangement = Arrangement.spacedBy(8.dp)

            ) {
                OutlinedTextField(
                    value = searchText.value,
                    onValueChange = {
                        searchText.value = it
                    },
                    leadingIcon = {
                        Icon(imageVector = Icons.Default.Search, contentDescription = null)
                    },
                    singleLine = true,
                    shape = RoundedCornerShape(30),
                    colors = OutlinedTextFieldDefaults.colors(
                        cursorColor = EDSColors.primaryColor,
                        focusedBorderColor = EDSColors.primaryColor,
                        focusedLeadingIconColor = EDSColors.primaryColor,
                    ),
                )
                LazyColumn(
                    verticalArrangement = Arrangement.spacedBy(8.dp)
                ) {

                    listProvince.value.forEachIndexed { index, province ->
                        item {
                            FilterChip(
                                modifier = Modifier.fillMaxWidth(),
                                selected = province.isSelected,
                                onClick = {
                                    val newList = listProvince.value.toMutableList()
                                    newList.forEach {
                                        it.isSelected = false
                                    }
                                    newList[index] =
                                        province.copy(isSelected = !province.isSelected)
                                    selectedProvince.value = newList[index]
                                    Log.d("Test select", selectedProvince.toString())
                                    listProvince.value = newList
                                },
                                label = {
                                    Text(
                                        province.provinceName, fontWeight = FontWeight.W300,
                                        maxLines = 1,
                                        overflow = TextOverflow.Ellipsis,
                                        modifier = Modifier
                                            .fillMaxWidth(.85f)
                                    )
                                },
                                trailingIcon = {
                                    if (province.isSelected)
                                        Icon(
                                            imageVector = Icons.Default.CheckCircle,
                                            contentDescription = null
                                        )
                                },
                                colors = FilterChipDefaults.filterChipColors(
                                    selectedContainerColor = EDSColors.greenCheck,
                                    selectedLabelColor = EDSColors.white,
                                    selectedTrailingIconColor = EDSColors.white
                                )
                            )
                        }
                    }
                }
            }
        },

        onDismissRequest = {
            onDisMiss()
        },
        confirmButton = {
            TextButton(onClick = {
                onConfirm(
                    selectedProvince.value.provinceName
                )
            }) {
                Text("Accept", color = EDSColors.primaryColor)
            }
        },
        dismissButton = {
            TextButton(
                onClick = {
                    onDisMiss()
                }
            ) {
                Text("Dismiss", color = EDSColors.notScheduleTextColor)
            }
        }
    )
}

I fixed it using mutableStateOf but i actually have no idea why it work.

Upvotes: 0

Views: 73

Answers (1)

BenjyTec
BenjyTec

Reputation: 10857

remember: A value stored using remember will be saved across recompositions.

mutableStateOf: A value stored using mutableStateOf will trigger a recomposition when it is changed.


var myText by remember { "Hello" }

If you use remember without mutableStateOf, changes to the myText variable will not cause a recomposition. Jetpack Compose cannot detect when you changed the variable.


var myText by mutableStateOf("Hello")

If you use mutableStateOf without remember, Jetpack Compose will detect when you change the myText variable. However, during the recomposition, the myText variable will be reset to the initial value.


var myText by remember { mutableStateOf("Hello") }

If you use remember and mutableStateOf, Jetpack Compose will detect when you change the myText variable. It triggers a recomposition, and the new value of myText will be saved during the recomposition. The UI is updated correctly with the new value.

Upvotes: 0

Related Questions