Как работает remember в Jetpack Compose

Ответ

remember сохраняет значение в композиции и возвращает его при последующих рекомпозициях. Если входные ключи (keys) изменились, значение пересчитывается.

var counter by remember { mutableStateOf(0) } // Сохраняется между рекомпозициями

Ключевые моменты:

  1. Значение сохраняется только в пределах текущей композиции
  2. При изменении ключей (переданных в remember(key1, key2)) значение пересоздается
  3. Под капотом использует механизм slot table Compose

Пример с ключами:

val result = remember(query) {
    heavyCalculation(query) // Пересчитается только при изменении query
}

Ответ 18+ 🔞

А, ну это же про тот самый remember, который у всех в головах путается! Слушай, представь себе: у тебя есть шкаф. Ты туда положил носки. Это и есть remember. Пока ты не переехал в другую квартиру (то есть композиция не пересоздалась полностью), носки лежат на том же месте, ты их каждый раз оттуда достаёшь, а не бежишь в магазин за новыми. Вот и вся магия, ёпта.

Вот смотри на этот кусок кода, тут всё как на ладони:

var counter by remember { mutableStateOf(0) } // Сохраняется между рекомпозициями

Видишь? Объявили counter. Compose отрендерил виджет, посчитал начальное значение (ноль) и — бац! — запомнил его в свою слот-таблицу, это у них там такая внутренняя штука, типа тайного хранилища. Дальше, что бы ни происходило, хоть тридцать рекомпозиций, значение counter будет браться из этого кэша. Не будет он каждый раз в ноль сбрасываться, ядрёна вошь! Иначе бы твой счётчик вообще не работал, это ж пиздопроебибна получилась бы.

Но есть нюанс, хитрая жопа! Всё хорошо, пока условия те же. А если они поменялись? Вот смотри второй пример:

val result = remember(query) {
    heavyCalculation(query) // Пересчитается только при изменении query
}

Вот тут уже интереснее. Ты remember передаёшь ключ — query. Пока query тот же самый, Compose такой: «А, этот результат я уже считал, зачем париться?» — и отдаёт тебе закэшированное значение. Но стоит query измениться (пользователь что-то новое ввёл), как Compose сразу понимает: «Опа, входные данные другие, старый результат не годится». Он накрывает медным тазом старое значение и запускает твой heavyCalculation заново, с новым query. Удобно же? Не нужно вручную следить, пересчитывать или хуй с горы — фреймворк сам всё умно делает.

Короче, суть в трёх пунктах, чтобы в дупу не дуло:

  1. Сохраняет значение между рекомпозициями одной композиции. Не теряет.
  2. Ключи решают всё. Нет ключей — значение вечное (в рамках композиции). Есть ключи — значение живёт, пока ключи не поменялись.
  3. Под капотом у них там своя магия со слот-таблицами, но тебе об этом можно особо не бздеть. Главное — понимать логику.

Запомни эту простую мысль: remember — это твой кэш внутри композиции. Хочешь, чтобы что-то не пересчитывалось на ровном месте — оберни в remember. Хочешь, чтобы пересчитывалось только при определённых условиях — добавь эти условия как ключи. Всё, больше ничё не надо, да похуй на остальное.