Skip to main content

Immutability

Components are essentially functions that receive data as parameters and are immutable (cannot be changed). When the props or state of a component change, the framework will create a new component instance with the updated information, because the previous component cannot be mutated.

While the component itself is immutable, it is easy to make it not thread safe by using mutable objects for props and state. Litho computes layout on a background thread, and if the objects that make up a component's props or state are mutated from another thread, then this may result in rendering different outputs for the same component.

Best Practice

Props and state must be kept as either primitive types (which are inherently immutable), or, if it's not possible to use a primitive type, an alternative that is also immutable.

Common Mistakes​

MistakeProblemFix
Using MutableList as propCan be modified from another threadUse List (immutable interface)
Using var in data classState can be mutatedUse val only in data classes
Modifying object after passing as propRace conditionsCreate new copy with changes

Examples​

Anti-Pattern: Mutable Props
// ❌ Incorrect - MutableList can be modified
class BadComponent(private val items: MutableList<String>) : KComponent()
Pattern: Immutable Props
// ✅ Correct - List is immutable interface
class GoodComponent(private val items: List<String>) : KComponent()
Anti-Pattern: Mutable Data Class Properties
// ❌ Incorrect - var properties can be mutated
data class BadUserData(
var name: String, // Can be changed!
var age: Int // Can be changed!
)
Pattern: Immutable Data Classes
// ✅ Correct - all properties are val
data class UserData(
val name: String,
val age: Int
)

See Also​