Hi, Just wondering if this code is okay to do? ``...
# compose
a
Hi, Just wondering if this code is okay to do?
Copy code
@Composable
fun doSomething(): State<String> {
   val (state, setState) = remember { mutableStateOf("") }
   ...
   // do something with state like for example 
   setState("Helo")
   
   ...
   return state
}
the idea is so that when I need call and do something, I can just do this:
Copy code
@Composable
fun CallSite() {
   val state by doSomething()

   Text(state)
}
Is this okay?
Another option I could take is to pass in a function instead like so:
Copy code
@Composable
fun doSomething(onStateChange: (String) -> Unit) {
   ...
   // do something with state like for example 
   onStateChange("Helo")
   ...
}
and so I’d be calling the it like this:
Copy code
@Composable
fun CallSite() {
   var state by remember { mutableStateOf("") }
   doSomething { state = it }
   Text(state)
}
But I feel like the first approach is cleaner? Thoughts?
s
both examples seem to have side-effects without using any of the side-effect apis, so I would recommend to avoid it. Also doesnt look very idiomatic, so other developers might be confused.
❤️ 1
1
Untitled.kt
Or there is the SideEffect api which might do what you're looking for: https://developer.android.com/develop/ui/compose/side-effects#sideeffect-publish
c
@stantronic where do you see “side-effects”? it changes a state and that is reflected in the retuned value. 🤔
@Archie I think the first approach is the more idiomatic way of handling
State
.
a
Sorry for the confusion @stantronic. In the example, the side effect calls are assumed to be called from a button click or inside a side effect launchers.
c
the only thing from an architetcural point of view - I’d but that function in a view model to encapsualte business logic from ui logic.
a
Thanks @Chrimaeon. In this case the I didnt want to move the logic to a ViewModel as everything are view related and was very simple that it doesn't have much logic.
c
😅 if you change that state you obviously have some business logic otherwise the whole function does not make sense. or do you just want to extract the same “logic” to be uses in several places?
a
In this case, the value is being taken from a library that is launched from a SideEffect, something like:
Copy code
@Composable
fun Something(): State<...> {
fun Something(): State<...> {
    val state = remember { mutableStateOf() }
    LaunchedEffect {
        LibraryCallThatOutputMultiplrValuesOvertime
        LibraryCallThatOutputMultiplrValuesOvertime
             .addListener { state.value = it }
     }
     }
    return state
}
So in this case I just want to display the value being outputed by the library.
s
a
Thanks @Stylianos Gakis. This is good to know.
c
yeah, definitely something I’d put in a view model. your Composable should not know anything about that “LibraryCallThatOutputMultiplrValuesOvertime”
a
Thanks @Chrimaeon. Might be right to do so. I'll review what I have. Thank you very much.
s
Since I'm doing this already, here's one which is quite more complex too, to show that this type of pattern can do quite a lot than most people realize 😀 https://cs.android.com/androidx/platform/frameworks/support/+/androidx-main:activity/activity-compose/src/main/java/androidx/activity/compose/ActivityResultRegistry.kt;l=80?q=rememberLauncher
❤️ 1
But I suppose it depends on what that value is that is emitted onal a flow overtime. If it's business logic and not something UI related then yeah sounds like a VM responsibility to me too.
❤️ 1
a
Aha! I didnt even realized that. Thanks. I got the same idea working on a React Native Project where this pattern is very commonly used as well.
The library could be anything say a location listener. In my opinion in that case, my view model dont need to launch the library, delegate it to the view and simply receive the values produced.
Thank @Stylianos Gakis really appreciate it.
🌟 1