Я знаю, что LaunchedEffect(key)
выполняется при запуске композиции, а также отменяется и снова выполняется при изменении key
. Однако я хочу, чтобы он выполнялся только один раз и никогда больше. Я использую следующий обходной путь, но мне кажется, что я что-то упускаю:
if (!launchedBefore) {
LaunchedEffect(null) {
//stuff
launchedBefore = true
}
}
Код выше работает просто отлично. Но это похоже на растянутый обходной путь, в то время как можно сделать что-то гораздо более простое. Я неправильно понимаю, как полностью работает LaunchedEffect?
Я пытался использовать null
и Unit
в качестве ключей, потому что они никогда не менялись, но код выполняется каждый раз, когда происходит композиция.
LaunchedEffect(Unit)
должен выполняться только один раз при запуске композиции. Единственный раз, когда он будет повторно выполнен во время рекомпозиции, это если он будет удален из дерева представления во время одной из предыдущих рекомпозиций. Примером может быть, если у вас есть это в условии, значение которого изменяется в какой-то момент (в блоке if
, блоке when
или любом другом условном операторе).
Я бы предположил, что проблема с перекомпоновкой заключается в другой части кода, которая не показана в вашем фрагменте. Проверьте, не вложен ли LaunchedEffect
в условный блок, что может привести к его выполнению после перекомпоновки.
Проблема не в LaunchEffect
или его key
параметре, а в верхнем компонуемом. Верхний компонуемый перекомпоновывается. Вероятно, вам следует отображать более подробную информацию о том, как называется LaunchEffect
и как звонить на сайты.
Рекомпозиция ищет ближайший компонуемый объект, на который могло повлиять изменение.
Я обычно передаю долгоживущую переменную для ключа, что-то вроде ViewModel
. Он будет выполняться только при инициализации ViewModel. Или использование запомненного сохраняемого логического значения может помочь.
val bool = rememberSaveable { true }
LaunchedEffect(key1 = bool) {
// do something
}