UPDATE: ```remember { derivedStateOf(block) }.let ...
# compose
y
UPDATE:
Copy code
remember { derivedStateOf(block) }.let {
  Snapshot.withoutReadObservation { it.value }
}
seems to do the trick and save me many headaches and complex code. Please let me know though if that's a bad approach. I'm trying to create an "effect" block: a Composable that returns
R
that only recalculates its value if the states read within it previously have changed, but it only does that recalculation at the point of time that it's called at. To state the problem concisely, I want to capture all the `StateObject`s read inside a block, and capture the state of those objects when they are read. Then, I want to later compare the state I captured with the current state according to the snapshot and hence determine if the previous calculation is now invalid. This is like a
remember
but based on the states read inside instead of explicit
keys
This is distinctly different from a
derivedStateOf
because seemingly the latter updates itself when one of its dependencies are updated sometimes before its
value
is read. This works:
Copy code
private val StateObject.currentRecord: StateRecord
  get() = firstStateRecord.withCurrent { it }

@Composable
public fun <R> effect(block: () -> R): R {
  var stateToRecord by remember { mutableStateOf<Map<StateObject, StateRecord>?>(null) }
  var result by remember { mutableStateOf<R?>(null) }
  if (stateToRecord?.any { (state, record) -> state.currentRecord != record } != false) {
    stateToRecord = buildMap {
      Snapshot.observe(readObserver = {
        put(
          it as StateObject,
          it.currentRecord
        )
      }) {
        result = block()
      }
    }
  }
  return result!!
}
There has to be a better way to do this, right? I'm a Compose newbie and just experimenting academically, so apologies for the abstract nature of this question
🤔 1
Reading into DerivedState's code, it seems to be doing similar things to my solution. What I can't figure out is how to make it only update on
value
calls, or otherwise restrict it to only update when I allow it to
s
Why would you want an effect that doesn't recompose automatically?