https://kotlinlang.org logo
a

Ash

06/17/2020, 12:09 AM
Building MVI with Kotlin StateFlow.
Copy code
val intentChannel = Channel<Intent>()
val state: StateFlow<ChannelState>
// Setup Ambient
val CurrAppState = ambientOf<ChannelState> { ChannelState.Edit }
In a Composable want to use the Ambient
Copy code
@Composable
fun Foo(appState: StateFlow<ChannelState>){
   val currState by appState.collectAsState(initial = ChannelState.NotEdit)
   CurrAppState.provides(currState)
Passing
currState
down the tree everything works perferct but if use
CurrAppState.current
get the wrong state. Think I am doing something dumb. Thanks for the help.
a

Adam Powell

06/17/2020, 12:25 AM
Copy code
@Composable
fun foo(appState: StateFlow<ChannelState>){
  val currState by appState.collectAsState(initial = ChannelState.NotEdit)
  Providers(CurrAppState provides currState) {
    // Content that should see currState
  }
🙏🏽 1
🤦🏽‍♂️ 1
but really, it's unlikely you want to use ambients for this use case
a

Ash

06/17/2020, 12:28 AM
So just pass it all the way down the tree?
a

Adam Powell

06/17/2020, 12:32 AM
that or use the lexical scope
a

alexgrafl

06/17/2020, 7:16 AM
Could you elaborate on the “lexical scope”, I could not find anything in the docs
z

Zach Klippenstein (he/him) [MOD]

06/17/2020, 12:31 PM
Lexical scope is basically the "syntax scope", ie the syntax scope. So in this case I think Adam means instead of passing your state explicitly through your tree as value parameters, have your intermediate composables take
children
composable functions (sometimes I've seen these referred to as "slots") and pass lambdas down that close over your state. This is a more extensible approach since it reduces coupling and dependencies on specific types. It's the same approach that composables like Button take, where there's an overload that accepts a composable function for text instead of a string.
👌 1
☝️ 1