I have two conflicting state changes being done fr...
# compose
r
I have two conflicting state changes being done from an event handler. I would like the first to be done, trigger recompose, and then the second (no-longer conflicting, since it would be based on the newly updated state) to be done. This isn't what happens, is there a way to force it? Note that these event handlers are passed in. I could potentially force recomposition between them, but that would be expensive when the event handlers don't need it. Minimal example in 🧵
Minimal example:
Copy code
class SharedClicker{
    private val actions = mutableMapOf<String, () -> Unit>()
    fun setAction(key: String, action: () -> Unit){
        actions[key] = action
    }

    fun removeAction(key: String){
        actions.remove(key)
    }

    fun click(){
        actions.values.forEach { it() }
    }
}

@Composable
fun Repro(){
    var pair by remember { mutableStateOf(0) }
    val sharedClicker = remember { SharedClicker() }

    Column(Modifier.padding(10.dp)) {
        ReproPart("a", pair, sharedClicker){ pair = it }
        Spacer(Modifier.height(20.dp))
        ReproPart("b", pair, sharedClicker){ pair = it }
    }
}

@Composable
fun ReproPart(key: String, n: Int, sharedClicker: SharedClicker, set: (Int) -> Unit){
    val lambda = { set(n + 1) }
    DisposableEffect(key, sharedClicker, lambda) {
        sharedClicker.setAction(key, lambda)
        onDispose {
            sharedClicker.removeAction(key)
        }
    }
    Row(Modifier.padding(4.dp).background(Color.Blue).clickable { sharedClicker.click() }){
        Text(n.toString())
    }
}
clicking one of the numbers should trigger both of the increment actions, and as such increment it twice. But it only does one, I suspect since the old value is captured in the action closure and not updated.
d
Could you eliminate the 'capturing' by passing
n
into
ReproPart
, in its
mutableState
form?
So that while processing
DisposableEffect
you're dealing directly with the
State
.
What the opposite of State Hoisting? 😅
r
I think that would work, but I'm trying to implement the thing like
SharedClicker
, not so much the particular lambdas.
and it would be a pita for where I'm running into it