Thread
#compose
    Francois Morvillier

    Francois Morvillier

    1 year ago
    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?
    Adam Powell

    Adam Powell

    1 year ago
    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.
    Francois Morvillier

    Francois Morvillier

    1 year ago
    Sorry, I'm not sure I quite understand. I was hoping something along these lines would be possible:
    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
    Adam Powell

    Adam Powell

    1 year ago
    Yes, this is possible. Mutable objects implemented using snapshot state types will be transitively observable. For example:
    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
    Francois Morvillier

    Francois Morvillier

    1 year ago
    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 😅
    Adam Powell

    Adam Powell

    1 year ago
    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