Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Custom saver rememberSaveable using derivedStateOf

I have a rememberSaveable that has some derivedStateOf doing some calculations to return a class as the output.

I've already added Parceable/Parcelize to the class and it still crashes and tells me to implement a custom saver. I believe this is because I'm using derivedStateOf. Am I allowed to save the state from a calculation output from derivedStateOf?

java.lang.IllegalArgumentException: DerivedState(value=MyClass(MyClass2())) cannot be saved using the current SaveableStateRegistry. The default implementation only supports types which can be stored inside the Bundle. Please consider implementing a custom Saver for this class and pass it to rememberSaveable().

The code looks like this

val someCalculation by rememberSaveable(someTriggering) {
        derivedStateOf {
            someCalculationThatReturnsAClass()
        }
    }
like image 311
Barrufet Avatar asked Oct 17 '25 13:10

Barrufet


1 Answers

You do not pass your custom saver to your rememberSaveable().

The params of rememberSaveable you are interested in are:

  • inputs - A set of inputs such that, when any of them have changed, will cause the state to reset and init to be rerun
  • saver - The Saver object which defines how the state is saved and restored

You only pass your someTriggering as an input.

The code could look like this:

val someCalculation by rememberSaveable(
   inputs = someTriggering,
   saver = YourCustomSaver
) {
    derivedStateOf {
        someCalculationThatReturnsAClass()
    }
}

Here you can see how to create a custom saver: Saver documentation

import androidx.compose.runtime.saveable.Saver

data class Holder(var value: Int)

// this Saver implementation converts Holder object which we don't know how to save
// to Int which we can save
val HolderSaver = Saver<Holder, Int>(
    save = { it.value },
    restore = { Holder(it) }
)

And how to use it: rememberSaveable documentation

import androidx.compose.runtime.saveable.rememberSaveable

val holder = rememberSaveable(saver = HolderSaver) { Holder(0) }

Am I allowed to save the state from a calculation output from derivedStateOf?

Yes, Google provides an example use of this in their Compose performance, use derivedStateOf paragraph.

Here is the code snippet they added:

val listState = rememberLazyListState()
LazyColumn(state = listState) {
  // ...
  }

val showButton by remember {
    derivedStateOf {
        listState.firstVisibleItemIndex > 0
    }
}

AnimatedVisibility(visible = showButton) {
    ScrollToTopButton()
}
like image 94
Abokyy Avatar answered Oct 20 '25 04:10

Abokyy