Data Classes
data class for anything that crosses a boundary — the network, disk, a navigation
argument. state class for anything that only exists while the app is running.
data class
A data class is annotated for you. It comes out @Serializable for
JSON and @Parcelize for Android, and implements Parcelable:
data class User(val id: String, val name: String) @Serializable
@Parcelize
data class User(val id: String, val name: String) : Parcelable Which is why $fetch can decode straight into one, and why $navigate can carry one as state without you writing a converter:
data class Show(val id: String, val title: String)
val shows: List<Show> = $fetch.get(url = "…/shows")
$navigate("/show/${show.id}", state = { title: show.title }) state class
Some state cannot be serialized and should not pretend otherwise — a lambda has no JSON form. state class is a plain Kotlin data class with no annotations attached:
state class DialogConfig(
val title: String,
val onConfirm: () -> Unit,
val onDismiss: () -> Unit
) Declaring that as a data class would be a compile error the moment the serializer
reached onConfirm. state class says up front that this value lives
and dies in memory.
See it happen
One keyword, three annotations — flip between them and watch the Kotlin change.
data class Show(val id: String, val title: String)
val show = Show("1", "Numberwang")
<Text>{show.title}</Text>data class picks up @Serializable and @Parcelize automatically, plus : Parcelable — it is ready to cross a network call or a navigation argument.
| Keyword | Gets | Use for |
|---|---|---|
data class | @Serializable + @Parcelize | API responses, stored records, navigation arguments |
state class | Plain Kotlin data class | UI state, callbacks, anything holding a lambda |
data class. If it holds a function, a Context, or a stream, it
is a state class.Where they live
Both work anywhere, but src/models/ is the conventional home for the ones shared
across screens, reachable as $app.models.User. See Project Structure.
import $app.models.User Annotations are case-insensitive
If you want to be explicit about something the shorthand already implies, spelling is loose:
@Serializable // or @serializable, @Serialize, @serialize
@Parcelize // or @parcelize, @Parcel, @parcel See Also
- State & Reactivity — holding and deriving state
- $fetch — decoding responses into a
data class - $import — embedding JSON as typed values at compile time
- $route / $screen — reading state carried across a navigation