본 내용은 학습을 위해 Everything you need to know about Side Effects in Jetpack Compose with examples을 보고 입맛대로 정리한 글입니다.
@Composable
fun LavaComposable() {
val context = LocalContext.current
// 🚫 don't call makeToast() here
// 토스트가 여러번 호출됨
Toast.makeToast(context, "💀", Toast.LENGTH_SHORT).show()
LaunchedEffect(Unit) {
// ✅ safe to run any non-composable code here
// LavaComposable이 Composition에 들어가면, 토스트는 한번만 호출되고 끝남
Toast.makeToast(context, "🏝️", Toast.LENGTH_SHORT).show()
}
}
@Composable
fun rememberAnalytics(user: User): FirebaseAnalytics {
val analytics: FirebaseAnalytics = remember {
/* ... */
}
// composition이 성공할 때마다 호출
SideEffect {
analytics.setUserProperty("userType", user.userType)
}
return analytics
}
@Composable
fun SurpriseComposable() {
Text("Wait for a surprise ⏰")
LaunchedEffect(key1 = Unit) {
delay(2000)
Toast.makeToast(context, "🎊 Surprise 🎊", Toast.LENGTH_SHORT).show()
}
}
@Composable
fun PoppingList(onListEmptied : () -> Unit) {
val list = remember { mutableStateListOf(1, 2, 3, 4, 5) }
LaunchedEffect(key1 = list.size) {
println("${list.size} items left")
if (list.isEmpty()) {
println("No more left! Bail")
onListEmptied()
}
}
Button(onClick = { list.removeLast() }) {
Text("Pop")
}
}
@Composable
fun NavigateOnStateChange(onNavigateAway : () -> Unit) {
val viewModel = viewModel { MyViewModel() }
val state = viewModel.state
when(state) {
UserJourneyCompleted -> LaunchedEffect(key1 = Unit) {
// make sure the navigation happens in a launched effect
// otherwise you risk having it called multiple times
onNavigateAway()
}
// .. your other states here
}
}
@Composable
fun BroadcastReceiver(intentFilter: IntentFilter, onReceive: (Intent) -> Unit) {
val context = LocalContext.current
DisposableEffect(key1 = context) {
val broadcastReceiver = object : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
onReceive(intent)
}
}
context.registerReceiver(broadcastReceiver, intentFilter)
onDispose {
context.unregisterReceiver(broadcastReceiver)
}
}
}
onDispose
@Composable
fun ButtonClick() {
val list = remember { mutableStateListOf(1, 2, 3, 4, 5) }
val context = LocalContext.current
Button(onClick = {
if (list.isEmpty()) {
Toast.makeText(context, "List is empty", Toast.LENGTH_SHORT).show()
} else {
list.removeLast()
}
}) {
Text("Pop: ${list.size} left")
}
}
@Composable
fun ShowSnackbar() {
Box(Modifier.fillMaxSize()) {
val snackbarHostState = remember { SnackbarHostState() }
val scope = rememberCoroutineScope()
Button(onClick = {
scope.launch {
val result = snackbarHostState.showSnackbar(
"Message deleted", actionLabel = "Undo"
)
when (result) {
SnackbarResult.Dismissed -> {
// nothing to do
}
SnackbarResult.ActionPerformed -> {
// TODO perform undo
}
}
}
}
) {
Text("Delete")
}
SnackbarHost(
hostState = snackbarHostState,
modifier = Modifier.align(Alignment.BottomCenter),
)
}
}