LaunchedEffect 살펴보기
LaunchedEffect는 Composable에서 컴포지션이 일어날 때 suspend fun을 실행해주는 Composable이다.
@Composable
fun LaunchedEffect(
key1: Any?,
block: suspend CoroutineScope.() -> Unit
) {
..
}
리컴포지션은 Composable의 State가 바뀔 때마다 일어나므로, 만약 매번 리컴포지션이 일어날 때마다 이전 LaunchedEffect가 취소되고 다시 수행된다면 매우 비효율적일 것이다. 이를 해결하기 위해 LaunchedEffect는 key라 불리는 기준값을 두어 key가 바뀔 때만 LaunchedEffect의 suspend fun을 취소하고 재실행한다.
예를 들어 TextField에 입력되는 문자를 snackbar로 보이게 만드는 상황을 생각해보자. 만약 문자가 바뀐다면 이전의 snackbar은 취소되고 새로운 snackbar가 보이도록 해야 한다.
이를 구현하기 위해서는 TextField의 Text가 바뀔 때마다 snackbar을 보이도록 하는 suspend fun이 취소되고 재수행되어야 한다.
이는 다음과 같이 구현할 수 있다.
1. TextField의 Text값이 변화하는 값을 저장하는 text변수를 만들기
2. text변수를 LaunchedEffect의 key값으로 주어 text가 바뀔 때마다 LaunchedEffect가 재수행되게 하기.
3. LaunchedEffect의 suspend fun block에서 snackbar 만들기
@Composable
fun KotlinWorldScreen() {
val scaffoldState = rememberScaffoldState()
var text by rememberSaveable { mutableStateOf("") } // 1. text변수
LaunchedEffect(text) { // 2.text 변수를 LaunchedEffect의 key로 설정
//3. 이 블록은 text가 바뀔 때마다 취소되고 재수행됨
scaffoldState.snackbarHostState.showSnackbar(
message = "Current Text is $text"
)
}
Scaffold(
scaffoldState = scaffoldState
) {
Column(modifier = Modifier.padding(16.dp)) {
OutlinedTextField(
value = text,
onValueChange = { text = it }
)
}
}
}
이 세가지를 수행하면 text의 State가 변화할 때마다 LaunchedEffect의 block이 재수행되어 그림1과 같은 결과가 나온다.
key값을 두개 이상 만들기
위에서는 text라는 하나의 변수값이 LauchedEffect의 재실행헤 대한 Trigger가 되었다. 하지만, 만약 LaunchedEffect의 block을 두개 이상의 변수에 의해 재실행 해야 할 때는 어떻게 해야할까?바로 key 값을 하나 더 명시하면 된다.
fun LaunchedEffect(
key1: Any?,
key2: Any?,
block: suspend CoroutineScope.() -> Unit
)
예를 들어 number라는 새로운 변수도 LaunchedEffect를 발생시키는 값이라면 단순히 text 뒤에 number을 명시해주는 것만으로 가능하다.
LaunchedEffect(text, number) {
scaffoldState.snackbarHostState.showSnackbar(
message = "Current Text is $text And Number is $number"
)
}
LaunchedEffect는 vararg를 사용하여 Key값을 무제한으로 줄 수 있도록 만들고 있다. 따라서 Key값은 무제한으로 추가가 가능하다.
fun LaunchedEffect(
vararg keys: Any?,
block: suspend CoroutineScope.() -> Unit
)