Omar Redani
Omar Redani

Reputation: 157

Why Exposed Dropdown Menu doesn't recomposed when their parent composable function parameters value changed

I'm wondering why my ExposedDropdownMenuBox doesn't recomposed when the parent composable function parameters value changed.

@Composable
private fun Title(
    isTitleEnabled: Boolean
) {

    ...

    ExposedDropdownMenuBox(
        expanded = expanded,
        onExpandedChange = {
            if (isTitleEnabled){
                expanded = !expanded
            }
        }
    ){...}
}

So why isTitleEnable value changed but ExposedDropdownMenuBox does not recomposed?

What I tried for now to solve the issue is to create a variable state then change it before passing it to the composable.

So my code after the changes looks something like this.

@Composable
private fun Title(
    isTitleEnabled: Boolean
) {

    ...

    var titleEnabled by remember { mutableStateOf(isTitleEnabled) }
    titleEnabled = isTitleEnabled

    ExposedDropdownMenuBox(
        expanded = expanded,
        onExpandedChange = {
            if (titleEnabled){
                expanded = !expanded
            }
        }
    ){...}
}

After these changes my ExposedDropdownMenuBox recomposed, but I'm wondering why it doesn't before adding the state variable.

Upvotes: 1

Views: 837

Answers (2)

Tarik
Tarik

Reputation: 106

It's understandable why the first case would skip ExposedDropdownMenuBox in recompositions. That's simply because after the initial composition, it's not tied to isTitleEnabled in the UI tree. You can think of it as taking an empty lambda for its onExpandedChange which doesn't depend on any State.

Another alternative to your workaround (which I think is fine) is to wrap ExposedDropdownMenuBox with key(isTitleEnabled) as such:

key(isTitleEnabled) {
    ExposedDropdownMenuBox(
        expanded = expanded,
        onExpandedChange = {
            if (isTitleEnabled) {
                expanded = !expanded
            }
        }
    ) {...}
}

Upvotes: 2

Subfly
Subfly

Reputation: 554

In the second code piece you have published, you are trying to change the state while it is recomposing as the dropdown already consumes the expanded value, and on expanding change it also tries to consume the 'expanded change' inside again, which possibly cancels the recomposition because this creates a side effect.

What you can do is rather than having the if value inside your dropdown, use a launched effect that listens to the isTitleEnabled value such as:

LaunchedEffect(isTitleEnabled) {
    if (isTitleEnabled) expanded = !expanded
}

I hope it helps as I can not understand how your expanded logic works as the codepieces you have published has no information about it. You can ask anything again on comments so I will edit my answer.

Upvotes: 2

Related Questions