useCached
useCached
is a hook that, rather than have to repeatedly make an expensive calculation, enables a component to calculate and maintain a cached value. It is calculated when the component is first added to the ComponentTree, and only recalculated when any of the dependencies provided in the useCached
declaration changes.
To familiarize yourself with the concept and rules for hooks, see the Introduction to Hooks page.
Example: Cached value with dependenciesβ
In the following code, useCached
is used to create and maintain an expensive-to-calculate value, which can be used multiple times across renders without repeating the expensive calculation.
Since the useCached
declaration defines a dependency, the value will be calculated when the component is attached to the ComponentTree, and then recalculated every time the dependency changes.
class UseCachedWithDependencyComponent : KComponent() {
override fun ComponentScope.render(): Component {
val number = useState { 1 }
val expensiveValue = useCached(number) { expensiveRepeatFunc("hello", number.value) }
return Column(style = Style.onClick { number.update { n -> n + 1 } }) {
child(Text(text = expensiveValue))
}
}
companion object {
private fun expensiveRepeatFunc(prefix: String, num: Int = 20): String {
return StringBuilder().apply { repeat(num) { append(prefix) } }.toString()
}
}
}
Example: Cached value without dependenciesβ
In the code below, since useCached
does not declare a dependency, the value will be calculated only once when the component is attached to the ComponentTree but will not be recalculated when the state value changes. The initial value of the state will always be used.
It's a common mistake to use the state in useCached
without defining it as a dependency then expect the cached value to be recalculated when the state is updated.
class UseCachedWithoutDependencyComponent : KComponent() {
override fun ComponentScope.render(): Component {
val number = useState { 1 }
val expensiveValue = useCached {
// state isn't declared as a dependency, so initial state value will always be used
expensiveRepeatFunc("hello", number.value)
}
return Column(style = Style.onClick { number.update { n -> n + 1 } }) {
child(Text(text = expensiveValue))
}
}