LeoColman

    LeoColman

    10 months ago
    @NoLiveLiterals
    @Composable
    fun DonationForm() {
      var selected by remember { mutableStateOf(values[1]) }
      val coroutineScope = rememberCoroutineScope()
      
      val clientSecret = coroutineScope.async { startDonation(selected.toLong().times(100)) }
    Hey guys! How to make
    clientSecret
    render again everytime
    selected
    is changed?
    selected
    gets it's state correctly, but
    clientSecret
    is being calculated only once (and not recalculating on recomposition)
    Doing
    val clientSecret = selected.run { coroutinescope.... }
    works
    I'm wondering if there's a way to do this differently
    Big Chungus

    Big Chungus

    10 months ago
    Hmm, try this?
    var clientSecret by remember { mutableStateOf(1L) }
    coroutineScope.launch {
      clientSecret = startDonation(selected.toLong().times(100))
    }
    I have no idea why selected.run works 🤦
    LeoColman

    LeoColman

    10 months ago
    lol
    Big Chungus

    Big Chungus

    10 months ago
    I'd assume selected.run compiles to the same thing as your first case (run being an inline fun)
    Maybe you're doing something different in the ommitted part (
    ...
    )?
    LeoColman

    LeoColman

    10 months ago
    I'll try again. My assumption was tthat with
    selected.run
    I'd trigger recomposition because
    selected
    would change inside a @Compose function
    Not inside the coroutine async block, if that makes any sense
    Big Chungus

    Big Chungus

    10 months ago
    But run is not "Composable
    LeoColman

    LeoColman

    10 months ago
    It isn't, but i'm inside
    DonationForm
    My thought was that triggering DonationForm recomposition would trigger the
    selected
    line
    The run was used only to get the value in an expression, which was what I thought could trigger the recomposition to work
    Big Chungus

    Big Chungus

    10 months ago
    Then I think my proposed solution is less hacky
    Give it a go
    You could also try using SideEffects API for this as well.
    That way you can control when the effects are executed better (as opposed to launching coroutine each composition)
    hfhbd

    hfhbd

    10 months ago
    what about
    derivedState
    ? Or
    remember(selected)
    ?
    LeoColman

    LeoColman

    10 months ago
    Your method works, @Big Chungus
    I don't know what either of those are @hfhbd 😂
    hfhbd

    hfhbd

    10 months ago
    derivedState
    updates the calculation if a state used inside the calculation block was changed. alternative using selected as a key for
    remember
    will result into the same behavior: if the key of remember was changed, the calculation will be executed again. Difference between remember and derivedState is optimization, in
    derivedState
    the compiler knows, the reason for recalculation was this state change, so it the recalculation can be scheduled right after the change of the state (change, recalculation, recomposing), and not after changing, recomposing and recalculation and recomposing again.
    Zach Klippenstein (he/him) [MOD]

    Zach Klippenstein (he/him) [MOD]

    10 months ago
    In general you don't want to perform side effects like launching async work directly from compositions. Use effect handlers.