Мой вопрос касается конструкций запоминания, используемых в Jetpack Compose и Kotlin. Как вы, скорее всего, уже знаете, я имею в виду именно эти:
var first = remember { mutableStateOf(true) }
var second by remember { mutableStateOf(true) }
Теперь мой вопрос: можно ли их использовать только в контексте составной функции? Я предполагаю, что ответ — да. Чтобы дать вам немного больше контекста, я сейчас работаю над проектом, сделал слой пользовательского интерфейса и часть навигации, а теперь пытаюсь реализовать интерфейс ViewModel. До сих пор я использовал два вышеперечисленных почти для каждой логики пользовательского интерфейса внутри составных элементов экрана. Но теперь я заметил, что больше не могу использовать их в классах данных типа UIState. Решением было просто объявить их как mutableState. Является ли это единственным эквивалентным способом их замены при переключении на часть внедрения hilt/viewModel/зависимости?
Я знаю, что это может быть очевидно, но я подумал, что это будет более проясняюще. Заранее спасибо!
Все различные функции remember
помечены @Composable
. Это делает их составными функциями, а это означает, что их необходимо вызывать из другой составной функции. Вы можете легко убедиться в этом, если действительно попытаетесь вызвать их из некомпонуемой функции. Вы получите эту ошибку:
Вызовы @Composable могут происходить только в контексте функции @Composable.
Функции remember
существуют для защиты вашего состояния от потери при рекомпозиции. Рекомпозиции фактически выполняют всю функцию заново, поэтому все, что не было запомнено, теряется. Вне составной функции эти функции бесполезны, даже если бы их можно было вызвать. Так что просто удалите remember
из всего, что вы используете в своей модели представления.
Тем не менее, если вы помните MutableState
, вам не следует использовать его в своей модели представления. MutableState также зависит от композиции. Хотя это не компонуемая функция (поэтому она не будет вызывать ошибок компиляции в вашей модели представления), ее может быть сложно правильно использовать вне кода компоновки. Вероятно, большую часть времени он будет работать так, как ожидалось, но вместо этого было бы лучше использовать MutableStateFlow
, как показано в документации Android. Хотя у них похожее имя, они совершенно разные: MutableState
взят из Android Compose SDK, где MutableStateFlow
интегрирован в сам язык программирования Kotlin. Однако концептуально они схожи: оба они инкапсулируют значение, за которым можно наблюдать изменения. How
хотя наблюдение сделано совсем другое.
Эмпирическое правило: всякий раз, когда вы хотите наблюдать изменения с течением времени, используйте MutableState
в составной функции и используйте поток для всего остального.
Большое спасибо за ваш действительно уточняющий ответ.