I am passing `SnapshotStateList<Char>` to a ...
# compose
a
I am passing
SnapshotStateList<Char>
to a composable function. But any changes to
SnapshotStateList's item(s)
doesn’t re-trigger the
LaunchedEffect
Any idea why? Code in thread.
Copy code
@Composable
fun Foo() {
    val otpCode = remember {
        List(5) {' '}.toMutableStateList()
    }

    OTPTextField(code = otpCode)

    ButtonPrimary(text = "Some Button, ${otpCode.joinToString()}") {
        otpCode[0] = '1'
    }
}

@Composable
fun OTPTextField(
    code: SnapshotStateList<Char>,
) {
    LaunchedEffect(code) {
        // this does not trigger on recomposition (caused by change in SnapshotStateList's item value) i.e, Button click
        Log.d("TAG", code.joinToString())
    }
}
ButtonPrimary's text changes(i.e,
Some Button, ${otpCode.joinToString()}
) after I click on the button, but
LaunchedEffect
fails to re-trigger
z
LaunchedEffect doesn't provide any state observation, and using your list as the key won't restart the effect because keys are simply compared via
equals
and for lists that's just a reference comparison, not a structural one. You could use
snapshotFlow
for this. Eg:
Copy code
LaunchedEffect(code) {
  snapshotFlow { code.joinToString() }
    .collect { Log.d(“TAG”, it) }
}
Note that you should still pass the list as a key, since the effect should restart if a different list instance is passed.
a
Thanks @Zach Klippenstein (he/him) [MOD]. I solved it by state hoisting, i.e., I am passing list of char. A new object of list will passed if any item of list is updated. Please let me which is a better solution.
👍🏻 1
z
That works too!