흐름을 유지할 수 있음 @Composable fun HelloScreen() { var name by rememberSaveable { mutableStateOf("") } HelloContent(name = name, onNameChange = { name = it }) } 6
활동 재생성 및 프로세스 종료 후에도 상태 보존 가능 var userTypedQuery by rememberSaveable(typedQuery, stateSaver = TextFieldValue.Sa mutableStateOf(TextFieldValue(text = typedQuery, selection = TextRange(typedQ } 7
로직과 상태 로직을 분리 가능 @Composable private fun rememberMyAppState(windowSizeClass: WindowSizeClass): MyAppState { return remember(windowSizeClass) { MyAppState(windowSizeClass) } } 8
UI 수명 주기에 따라 상태 범위 지정 필요 상태 소유자로서의 컴포저블 상태와 로직이 단순하면 컴포저블에 UI 로직과 UI 요소 상태 포함 가능 단순한 상태는 내부 유지 가능 (예: 애니메이션 상태) @Composable fun ChatBubble(message: Message) { var showDetails by rememberSaveable { mutableStateOf(false) } ClickableText( text = AnnotatedString(message.content), onClick = { showDetails = !showDetails } ) if (showDetails) { Text(message.timestamp) } } 13
통해 상태를 관리하는 것이 적절함 ViewModel은 컴포지션 외부에 저장되며, UI 상태의 가장 낮은 공통 상위 요소 역할을 수행 class ConversationViewModel(channelId: String, messagesRepository: MessagesReposi val messages = messagesRepository.getLatestMessages(channelId) .stateIn(viewModelScope, SharingStarted.WhileSubscribed(5_000), emptyList fun sendMessage(message: Message) { /* ... */ } } 15
하는 비즈니스 로직이 있다면 ViewModel에서 상태 관리 사용자의 입력에 따라 UI 상태를 변경하는 예시: class ConversationViewModel : ViewModel() { var inputMessage by mutableStateOf("") private set val suggestions: StateFlow<List<Suggestion>> = snapshotFlow { inputMessage } .filter { hasSocialHandleHint(it) } .mapLatest { getHandle(it) } .mapLatest { repository.getSuggestions(it) } .stateIn(viewModelScope, SharingStarted.WhileSubscribed(5_000), empty fun updateInput(newInput: String) { inputMessage = newInput } } 16
및 프로세스 종료 후에도 UI 요소 상태 복원 가능 @Composable fun ChatBubble(message: Message) { var showDetails by rememberSaveable { mutableStateOf(false) } ClickableText( text = AnnotatedString(message.content), onClick = { showDetails = !showDetails } ) if (showDetails) { Text(message.timestamp) } } 20
상태 유지 SavedStateHandle을 활용하여 시스템 종료 후에도 상태 복원 가능 class ConversationViewModel( savedStateHandle: SavedStateHandle ) : ViewModel() { var message by savedStateHandle.saveable(stateSaver = TextFieldValue.Saver) { mutableStateOf(TextFieldValue("")) } private set fun update(newMessage: TextFieldValue) { message = newMessage } } 22
활용하여 지속적으로 UI 상태 업데이트 가능 private const val CHANNEL_FILTER_SAVED_STATE_KEY = "ChannelFilterKey" class ChannelViewModel( channelsRepository: ChannelsRepository, private val savedStateHandle: SavedStateHandle ) : ViewModel() { private val savedFilterType: StateFlow<ChannelsFilterType> = savedStateHandle.getStateFlow( key = CHANNEL_FILTER_SAVED_STATE_KEY, initialValue = ChannelsFilterType.ALL_CHANNELS ) fun setFiltering(requestType: ChannelsFilterType) { savedStateHandle[CHANNEL_FILTER_SAVED_STATE_KEY] = requestType } } 23
없음 UI 상태를 제어하여 UI를 변경 상태가 변경되면 Compose는 변경된 UI 트리 부분을 다시 생성 컴포저블은 상태를 수락하고 이벤트를 노출 가능 var name by remember { mutableStateOf("") } OutlinedTextField( value = name, onValueChange = { name = it }, label = { Text("Name") } ) 25
및 이벤트 처리 mutableStateOf를 사용하여 UI 상태를 저장 class MyViewModel : ViewModel() { private val _uiState = mutableStateOf<UiState>(UiState.SignedOut) val uiState: State<UiState> get() = _uiState } 29