Using MutableState, MutableStateFlow or MutableLiv...
# compose
f
Using MutableState, MutableStateFlow or MutableLiveData (are there others?) in a @Composable function will automatically trigger recomposition when the underlying data changes. Say I have my own DataHolder to some data (a graph) and that my DataHolder receives notifications when the underlying graph data changes. It also notifies whoever is observing it. Is there a way to use my DataHolder in @Composable functions in the same way we would use MutableState so that it will trigger recomposition? For example implementing the State<T> interface?
a
Yes, all of these work the same way:
val result = remember { mutableStateOf(initialValue) }
Use a
LaunchedEffect
or
DisposableEffect
to manage a subscription to an external observable type
return result
The effect should set the value of
result
to the new value of the external observable whenever it changes.
f
Sorry, I'm not sure I quite understand. I was hoping something along these lines would be possible:
Copy code
class DataHolder: State<Graph> { // extend my current DataHolder in some way so that it works like a MutableState. Implementing State<Graph> would be ideal but I suppose it's not that simple
    //...
}

@Composable 
fun DataView(dataHolder: DataHolder) {
    Text("graph size: ${dataHolder.graph.getSize()}")
}

// ...
graph.addNode(...) // notifies dataHolder and triggers recomposition
a
Yes, this is possible. Mutable objects implemented using snapshot state types will be transitively observable. For example:
Copy code
class Graph {
  private val nodes = mutableStateListOf<Node>()

  fun addNode(node: Node) {
    nodes += node
  }

  fun getSize(): Int = nodes.size
}
the above class is observable to compose, since its internal mutable state is implemented using the
SnapshotStateList
returned by
mutableStateListOf
the implementation of mutable internals is what matters, not the
State<T>
type
f
I wouldn't want to make my Graph class dependent on Compose though, just my DataHolder (which is subscribed to Graph). I'm not being intentionally difficult 😅
a
I think the biggest challenge you're likely to run into then is once we start doing more multithreaded composition. We rely on a combination of snapshots and immutability as a thread safety mechanism