๋ถ์ ํจ๊ณผ - LaunchedEffect, DisposableEffect, rememberCoroutineScope
์ง๊ธ๊น์ง๋ ์ฌ์ฉ์๊ฐ ๋ฒํผ์ ๋๋ฌ์ผ ๋ญ๊ฐ ์ผ์ด๋๋ ์ฝ๋๋ง ๋ดค๋ค. ์ด๋ฒ์ "ํ๋ฉด์ด ์ฒ์ ๋ ๋ ๋ ์๋์ผ๋ก ํ ๋ฒ ์คํ๋๋ ์ผ"์ ๋ค๋ค๋ณด์. ๋ชฉ๋ก ํ๋ฉด์ ๋ค์ด๊ฐ๋ฉด ์๋ฒ ์ถ์ฒ ํ ์ผ์ ์๋์ผ๋ก ํ ๋ฒ ๊ฐ์ ธ์ค๊ฒ ๋ง๋ค์ด๋ณด์.
์ด๋ ๊ฒ ํ๋ฉด ๋ ๊ฒ ๊ฐ์๋ฐ
@Composable
fun TodoListScreen(viewModel: TodoViewModel) {
viewModel.importFromServer() // ํ๋ฉด ๋ค์ด์ค๋ฉด ๋ฐ๋ก ์คํ?
// ... ๋๋จธ์ง UI
}์ปดํฌ์ ๋ธ ํจ์ ๋งจ ์์ ๊ทธ๋ฅ ํธ์ถ๋ฌธ์ ์ ์ด๋ดค๋ค. ๊ทผ๋ฐ ์ด๋ ๊ฒ ํ๋ฉด ํ๋ฉด์ ๋ค์ด์ฌ ๋ ํ ๋ฒ๋ง ์คํ๋๋ ๊ฒ ์๋๋ผ, ๋ฆฌ์ปดํฌ์ง์
์ด ์ผ์ด๋ ๋๋ง๋ค ๋ค์ ์คํ๋๋ค. ์ฒดํฌ๋ฐ์ค๋ฅผ ํ๋ ๋๋ฅด๋ฉด uiState๊ฐ ๋ฐ๋์ด์ TodoListScreen์ด ๋ค์ ๊ทธ๋ ค์ง๋๋ฐ, ๊ทธ๋๋ง๋ค importFromServer()๊ฐ ๋ ํธ์ถ๋ผ์ ์๋ฒ์ ๋ ์์ฒญ์ ๋ณด๋ธ๋ค. ์ฒดํฌ๋ฐ์ค๋ฅผ ๋ค์ฏ ๋ฒ ๋๋ฅด๋ฉด ๋คํธ์ํฌ ์์ฒญ์ด ๋ค์ฏ ๋ฒ ๋ ๋๊ฐ๋ค.
์ ์ด๋ฌ๋๋ฉด
์ปดํฌ์ ๋ธ ํจ์ ๋ณธ๋ฌธ์ "ํ๋ฉด์ ์ด๋ป๊ฒ ๊ทธ๋ฆด์ง"๋ฅผ ๊ธฐ์ ํ๋ ์๋ฆฌ๋ค. ๋ฆฌ์ปดํฌ์ง์ ๋ ๋๋ง๋ค ์ฒ์๋ถํฐ ๋ค์ ์คํ๋๋ ๊ฒ ์ ์ ๋์์ด๋ค. ๊ทผ๋ฐ ๋คํธ์ํฌ ์์ฒญ ๊ฐ์ ๊ฑด "๊ทธ๋ฆด ๋๋ง๋ค ๋ฐ๋ณตํด์ผ ํ๋ ์ผ"์ด ์๋๋ผ "ํน์ ์์ ์ ๋ฑ ํ ๋ฒ(๋๋ ํน์ ์กฐ๊ฑด์์๋ง) ์ผ์ด๋์ผ ํ๋ ์ผ"์ด๋ค. ์ด๋ ๊ฒ ๋ฆฌ์ปดํฌ์ง์ ์ ํ๋ฆ๊ณผ ์๊ด์์ด "ํ ๋ฒ๋ง, ๋๋ ํน์ ์กฐ๊ฑด์์๋ง" ์ผ์ด๋์ผ ํ๋ ์ผ์ ๋ถ์ ํจ๊ณผ(Side Effect)๋ผ๊ณ ๋ถ๋ฅด๊ณ , ์ปดํฌ์ฆ๋ ์ด๊ฑธ ์ํ ์ ์ฉ ๋๊ตฌ๋ฅผ ๋ฐ๋ก ์ค๋ค.
LaunchedEffect - ์ฒ์ ํ ๋ฒ(๋๋ key๊ฐ ๋ฐ๋ ๋)๋ง ์คํ
@Composable
fun TodoListScreen(viewModel: TodoViewModel) {
LaunchedEffect(Unit) {
viewModel.importFromServer()
}
// ... ๋๋จธ์ง UI
}[์ด๋ฏธ์ง: ๋ชฉ๋ก ํ๋ฉด์ ์ฒ์ ๋ค์ด์์ ๋ ๋ก๋ฉ๋ฐ๊ฐ ํ ๋ฒ ๋จ๊ณ , ์ดํ ์ฒดํฌ๋ฐ์ค๋ฅผ ๋๋ฌ๋ ๋ค์ ๋ก๋ฉ๋ฐ๊ฐ ๋จ์ง ์๋ ํ๋ฉด]
LaunchedEffect(Unit)์ "์ด ์ปดํฌ์ ๋ธ์ด ์ฒ์ ํ๋ฉด์ ๋ํ๋ ๋ ๋ธ๋ก ์์ ์ฝ๋๋ฅผ ์ฝ๋ฃจํด์ผ๋ก ํ ๋ฒ ์คํํ๊ณ , ๊ทธ ์ดํ ๋ฆฌ์ปดํฌ์ง์
์ด ์ผ์ด๋๋ ๋ค์ ์คํํ์ง ์๋๋ค"๋ ๋ป์ด๋ค. ๊ดํธ ์์ Unit์ "key"๋ผ๊ณ ๋ถ๋ฅด๋๋ฐ, ์ด key ๊ฐ์ด ๋ฐ๋ ๋๋ง ๋ธ๋ก์ ๋ค์ ์คํํ๋ค. Unit์ ์ ๋ ์ ๋ฐ๋๋ ๊ฐ์ด๋๊น "๋ฑ ํ ๋ฒ๋ง"์ด ๋๋ ๊ฑฐ๋ค. ๋ง์ฝ LaunchedEffect(todoId)์ฒ๋ผ ์ด๋ค ๊ฐ์ key๋ก ๋ฃ์ผ๋ฉด, ๊ทธ ๊ฐ์ด ๋ฐ๋ ๋๋ง๋ค(์: ๋ค๋ฅธ ์์ธ ํ๋ฉด์ผ๋ก ๋์ด๊ฐ ๋) ๋ค์ ์คํ๋๋ค.
DisposableEffect - ๋ญ๊ฐ ๋ฑ๋กํ์ผ๋ฉด ์ ๋ฆฌ๋ ํด์ค์ผ ํ ๋
์๋ฅผ ๋ค์ด ํ๋ฉด์ด ๋ ์๋ ๋์๋ง ์์คํ ๋ค๋ก๊ฐ๊ธฐ๋ฅผ ๊ฐ๋ก์ฑ๊ณ ์ถ๋ค๊ณ ํด๋ณด์.
@Composable
fun TodoDetailScreen(onBack: () -> Unit) {
val backDispatcher = LocalOnBackPressedDispatcherOwner.current?.onBackPressedDispatcher
DisposableEffect(backDispatcher) {
val callback = object : OnBackPressedCallback(true) {
override fun handleOnBackPressed() {
onBack()
}
}
backDispatcher?.addCallback(callback)
onDispose {
callback.remove()
}
}
// ... ๋๋จธ์ง UI
}DisposableEffect๋ LaunchedEffect๋ ๋น์ทํ๊ฒ ํน์ ์์ ์ ์ฝ๋๋ฅผ ์คํํ์ง๋ง, "์ ๋ฆฌ(cleanup)" ์ฝ๋๋ฅผ ๊ฐ์ด ๋ฐ๋๋ค๋ ์ ์ด ๋ค๋ฅด๋ค. ์ฌ๊ธฐ์๋ ๋ค๋ก๊ฐ๊ธฐ ์ฝ๋ฐฑ์ ๋ฑ๋ก(addCallback)ํ๋๋ฐ, ์ด ํ๋ฉด์ด ์ฌ๋ผ์ง ๋ ๊ทธ ์ฝ๋ฐฑ์ ํด์ง(callback.remove())ํ์ง ์์ผ๋ฉด ์ฝ๋ฐฑ์ด ๋ฉ๋ชจ๋ฆฌ์ ๊ณ์ ๋จ์์ ๋ค๋ฅธ ํ๋ฉด์์๊น์ง ์๋ฑํ๊ฒ ๋ฐ์ํ ์ ์๋ค. onDispose { } ๋ธ๋ก์ ๊ทธ ์ ๋ฆฌ ์ฝ๋๋ฅผ ์ ์ด๋๋ฉด, ์ด ์ปดํฌ์ ๋ธ์ด ํ๋ฉด์์ ์ฌ๋ผ์ง๊ฑฐ๋ key๊ฐ ๋ฐ๋์ด์ ํจ๊ณผ๊ฐ ๋ค์ ์คํ๋ ๋ ์๋์ผ๋ก ํธ์ถ๋๋ค.
rememberCoroutineScope - ์ฌ์ฉ์๊ฐ ๋๋ฅผ ๋๋ง ์ฝ๋ฃจํด์ ์คํํ๊ณ ์ถ์ ๋
LaunchedEffect๋ ์ปดํฌ์ ๋ธ์ด ํ๋ฉด์ "๋ ์๋ ๋์"์ ๊ธฐ์ค์ผ๋ก ์๋ ์คํ๋๋ค. ๊ทผ๋ฐ ๋ฒํผ ํด๋ฆญ์ฒ๋ผ ์ฌ์ฉ์๊ฐ ์ง์ ์ก์
์ ์ทจํ์ ๋๋ง ์ฝ๋ฃจํด์ ์คํํ๊ณ ์ถ์ผ๋ฉด ์ด๋ป๊ฒ ํ ๊น? onClick ๋๋ค๋ suspend ํจ์๊ฐ ์๋๋ผ์ ๊ทธ ์์์ ๋ฐ๋ก delay()๋ suspend fun์ ํธ์ถํ ์ ์๋ค.
@Composable
fun TodoListScreen(viewModel: TodoViewModel) {
val scope = rememberCoroutineScope()
val snackbarHostState = remember { SnackbarHostState() }
Button(onClick = {
scope.launch {
snackbarHostState.showSnackbar("ํ ์ผ์ ์ถ๊ฐํ๋ค")
}
}) {
Text("์ถ๊ฐ")
}
}rememberCoroutineScope()๋ "๋ฆฌ์ปดํฌ์ง์
์ด ์ผ์ด๋๋ ์ ์ง๋๋ ์ฝ๋ฃจํด ์ค์ฝํ"๋ฅผ ํ๋ ๋ง๋ค์ด์ค๋ค. ์ด ์ค์ฝํ๋ฅผ onClick์ฒ๋ผ suspend๊ฐ ์๋ ์ฝ๋ฐฑ ์์์ .launch { }๋ก ์ฐ๋ฉด, ๊ทธ ์์์๋ suspend ํจ์๋ฅผ ์์ ๋กญ๊ฒ ํธ์ถํ ์ ์๋ค. LaunchedEffect๋ "ํ๋ฉด ์๋ช
์ฃผ๊ธฐ์ ๋ง์ถฐ ์๋์ผ๋ก" ์คํ๋๊ณ , rememberCoroutineScope๋ "์ฌ์ฉ์ ์ด๋ฒคํธ์ ๋ง์ถฐ ๋ด๊ฐ ์ํ ๋" ์คํ๋๋ค๋ ์ฐจ์ด๋ค.
์ ๋ฆฌ
- ๋ฆฌ์ปดํฌ์ง์
๋ง๋ค ๋ฐ๋ณต๋๋ฉด ์ ๋๋ ์ผ(๋คํธ์ํฌ ์์ฒญ, ๋ฆฌ์์ค ๋ฑ๋ก ๋ฑ)์ ์ปดํฌ์ ๋ธ ํจ์ ๋ณธ๋ฌธ์ ๊ทธ๋ฅ ์ ์ผ๋ฉด ์ ๋๊ณ ,
LaunchedEffect๊ฐ์ ๋ถ์ ํจ๊ณผ API๋ฅผ ์จ์ผ ํ๋ค LaunchedEffect(key)๋ key๊ฐ ๋ฐ๋ ๋๋ง ๋ค์ ์คํ๋๊ณ ,DisposableEffect๋onDispose { }๋ก ์ ๋ฆฌ ์ฝ๋๊น์ง ํจ๊ป ๊ด๋ฆฌํ๋ค- ์ฌ์ฉ์ ์ด๋ฒคํธ(ํด๋ฆญ ๋ฑ)์์ ์ฝ๋ฃจํด์ ์คํํ๋ ค๋ฉด
rememberCoroutineScope()๋ก ๋ฐ์ ์ค์ฝํ๋ฅผ ์ด๋ค
๋ค์ ๊ธ์์๋ ์ฒดํฌ๋ฐ์ค๋ฅผ ๋๋ฅผ ๋ ๋ฐฐ๊ฒฝ์์ด ์ค๋ฅด๋ฅต ๋ฐ๋๋ ๊ฒ์ฒ๋ผ, ์ํ ๋ณํ์ ์ ๋๋ฉ์ด์ ์ ์ ํ๋ ๋ฐฉ๋ฒ์ ๋ณด๊ฒ ๋ค.
