https://kotlinlang.org logo
#compose
Title
# compose
n

nuhkoca

04/22/2022, 2:34 PM
Hello, how one can define a multiple derivedStatedOf? I have a code like below but they are called constantly when I log and recomposition happening. As far as I understand correctly, recomposition should only happen when
isPageTitleReached
and
isContentScrolled
changed, right?
Copy code
val isPageTitleReached by derivedStateOf {
    remember {
        lazyListState.firstVisibleItemScrollOffset > 500
    }
}
val isContentScrolled by derivedStateOf {
    remember {
        lazyListState.firstVisibleItemScrollOffset > 600
    }
}
👀 2
1
m

myanmarking

04/22/2022, 2:42 PM
you inverted the function calls. It should be remember{derivedStateOf ..}
remembers like that are useless. The block inside will only run once.
n

nuhkoca

04/22/2022, 2:46 PM
ohh really? fixing this right away, thanks for the heads-up. Will update you!
btw why it is like I did in the official doc?
Copy code
val highPriorityTasks by remember(highPriorityKeywords) {
        derivedStateOf { todoTasks.filter { it.containsWord(highPriorityKeywords) } }
    }
m

myanmarking

04/22/2022, 2:48 PM
the reason they are called constantly is because derivedState that in not remembered will create a new instance every recomposition
remember{derivedState}, you have derivedState{remember} ?
n

nuhkoca

04/22/2022, 2:49 PM
ahh my bad sorry you are right
Hey @myanmarking can I have something like this or is it a good way on Compose? Basically I’d like to hold all variables inside a data class but wondering if
remember
and
derivedStateOf
would work as expected in my example?
Copy code
@Composable
private fun rememberScrollState(
    lazyListState: LazyListState,
    firstCondition: Int,
    secondCondition: Int
) = remember(firstCondition, secondCondition) {
    ScrollState(lazyListState, firstCondition, secondCondition)
}
Copy code
@Immutable
private data class ScrollState(
    val lazyListState: LazyListState,
    val firstCondition: Int,
    val secondCondition: Int
) {
    val isPageTitleReached by derivedStateOf {
        if (lazyListState.firstVisibleItemIndex == 0) {
            lazyListState.firstVisibleItemScrollOffset > firstCondition
        } else {
            true
        }
    }
    val isHeroScrolled by derivedStateOf {
        if (lazyListState.firstVisibleItemIndex == 0) {
            lazyListState.firstVisibleItemScrollOffset > secondCondition
        } else {
            true
        }
    }
}
m

myanmarking

04/22/2022, 5:18 PM
Ya it should work. You should probably add the lazyliststate to remeber param as well
And probably change immutable to stable
n

nuhkoca

04/22/2022, 5:20 PM
Awesome, applying right now. Thanks for the quick turnaround, appreciate it 🙏
m

Michael Paus

04/22/2022, 5:29 PM
Which leads me to the question whether a data class with only val parameters needs any of these qualifiers (@Immutable, @Stable) at all. I thought such a data class is considered stable by default.
m

myanmarking

04/22/2022, 5:33 PM
Well, you can have a val that is unstable. It is not the only requirement. Im not sure about this case would have to check, but it doesnt hurt adding it
t

Tash

04/22/2022, 7:52 PM
IIRC the Compose compiler can infer immutability and stability only on classes which are compiled in modules where the Compose compiler enabled. So even if your
data class
has `val`s where nothing is backed by mutable data, it won’t be inferred as immutable unless it is in a module w/ the Compose compiler. Also if your
data class
contains a
val list: List<Foo>
the compiler can’t infer stability even if
Foo
is stable (there’s an open issue). For that you’d have to explicitly annotate that class with `@Immutable`/`@Stable`. Recently read about this here https://chris.banes.dev/composable-metrics/
m

Michael Paus

04/23/2022, 10:01 AM
@Tash Very interesting reading, especially the link to https://issuetracker.google.com/issues/216791427 I proposed exactly that here some months ago but the idea was bluntly rejected.
9 Views