Чек-лист правильного Compose
Собираем весь курс в один практический чек-лист, по которому стоит сверяться при написании Compose-кода.
Хороший Compose-код — это предсказуемый поток данных, аккуратное состояние и узкая область перерисовки.
Состояние
- Изменяемое состояние — только через
remember { mutableStateOf(...) }. - Пользовательский ввод, который должен пережить поворот, — через
rememberSaveable. - Логику и долгоживущие данные экрана — в
ViewModel, наружу отдавать read-onlyStateFlow. - Подписка на поток — через
collectAsState.
Поток данных
- Данные текут вниз через параметры, события — вверх через колбэки (однонаправленный поток).
- Низкоуровневые компоненты делайте stateless и поднимайте состояние (
state hoisting) ровно до нужного уровня. - Состояние читайте как можно ниже по дереву, чтобы сузить recomposition.
UI и раскладка
- Размеры — в
dp, шрифты — вsp. - Помните про порядок модификаторов: он влияет на результат.
- Каркас экрана — на
Scaffold; не забывайте применятьinnerPadding. - Цвета — через роли темы (
primary,surface,onPrimary), а не жёсткие значения.
Списки и эффекты
- Длинные списки —
LazyColumn/LazyRow, для изменяемых списков задавайтеkey. - Побочные эффекты — только через effect handlers:
LaunchedEffectдля запуска при входе,rememberCoroutineScopeдля реакции на события. - Никаких запросов и логов в голом теле composable.
Мини-пример «всё вместе»
@Composable
fun NotesScreen(viewModel: NotesViewModel = viewModel()) {
val notes by viewModel.notes.collectAsState()
Scaffold(
topBar = { TopAppBar(title = { Text("Заметки") }) }
) { padding ->
LazyColumn(modifier = Modifier.padding(padding)) {
items(notes, key = { it.id }) { note ->
Text(text = note.title, modifier = Modifier.padding(16.dp))
}
}
}
}В этом экране собрано почти всё: ViewModel + StateFlow + collectAsState, каркас Scaffold с TopAppBar, ленивый список с ключами и модификаторы с отступами.
Как работает под капотом
Каждый пункт чек-листа опирается на одну идею: Compose перерисовывает то, что зависит от изменившегося состояния. Узкое чтение состояния, стабильные параметры, ленивые списки и эффекты вне тела — всё это способы помочь движку перерисовывать как можно меньше и предсказуемее. Понимая механизм recomposition, вы выводите эти правила сами, а не заучиваете.
Частые ошибки (сводно)
- Состояние без
remember— «несчитающий» счётчик. - Побочные эффекты в теле composable — повторяются на каждой перерисовке.
- Списки без ключей и большие
ColumnвместоLazyColumn— тормоза. - Жёсткие цвета вместо ролей темы — сломанная тёмная тема.
Итог
- Состояние — через
remember/rememberSaveable/ViewModel, поток данных однонаправленный. - Список — ленивый и с ключами; эффекты — через effect handlers.
- Сужайте область recomposition: ниже читайте состояние, держите параметры стабильными.
Проверьте себя
1. Какой набор инструментов корректно покрывает состояние экрана со списком в Compose?
AОбычные переменные без remember и Column
BViewModel + StateFlow + collectAsState, Scaffold и LazyColumn с key
CТолько rememberSaveable для всего
DXML-разметка и findViewById
2. Где НЕ должны находиться побочные эффекты (запросы, логи)?
AВ LaunchedEffect
BВ голом теле composable-функции
CВ rememberCoroutineScope при клике
DВ методах ViewModel