💡Hoisting
변수의 선언과 초기화를 분리한 후 선언 부분만 코드의 최상단으로 옮기는 행위
- 컴포저블 내부에서 관리하던 상태를 상단으로 호이스팅 하는 것
- 상태 관련된 변수를 매개변수로 바꿈으로써 이루어짐
- value: T ⇒ 컴포저블이 다룰 상태 값
- onValueChange: (T) → Unit ⇒ 상태의 값을 변경하도록 요청하는 이벤트이며, T는 컴포저블에 제안할 새로운 값
- 상태를 호이스팅함으로써 여러 컴포저블과 상태를 공유할 수 있으며 상태를 어디에나 저장할 수 있음
- 상태는 내려가고 이벤트는 올라가는 단방향 데이터 흐름 패턴이 사용 됨
💡ViewModel
- 크기가 비교적 큰 데이터는 UI 코드로 저장하기에 부담이 있으므로 따로 분리하여 데이터를 보관하고 UI를 변경하기 위해 ViewModel 사용
- 액티비티와 같은 라이프사이클을 가지기 때문에 remember를 신경 쓰지 않아도 됨
- ex)
class MainActivity : ComponentActivity() {
private val viewModel by viewModels<MainViewModel>() // viewModel 불러오기
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
Column(
modifier =Modifier.fillMaxSize(),
verticalArrangement = Arrangement.Center,
horizontalAlignment = Alignment.CenterHorizontally,
) {
Text(
viewModel.data.value, // viewModel에 정의된 데이터 불러와서 사용
fontSize = 30.sp,
)
Button(onClick = {
viewModel.data.value = "World"
}) {
Text("변경")
}
}
}
}
class MainViewModel: ViewModel() {
val data = mutableStateOf("Hello") // remember 없이 데이터 정
}
- gradle에 viewModel을 추가한 경우는 사용 방법이 다르니 참고!
- 현재 위 코드처럼 view내부에서 viewModel의 데이터를 변경하는 것은 바람직하지 않기 때문에 아래 코드처럼 수정
class MainActivity : ComponentActivity() {
private val viewModel by viewModels<MainViewModel>() // viewModel 불러오기
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
Column(
modifier =Modifier.fillMaxSize(),
verticalArrangement = Arrangement.Center,
horizontalAlignment = Alignment.CenterHorizontally,
) {
Text(
viewModel.data.value, // viewModel에 정의된 데이터 불러와서 사용
fontSize = 30.sp,
)
Button(onClick = {
// viewModel.data.value = "World" 외부 접근 금지를 해놓았으므로 여기서는 data 변경 불가능
viewModel.changeValue() // viewModel에 작성한 변경 함수 불러오기
}) {
Text("변경")
}
}
}
}
class MainViewModel: ViewModel() {
private val _data = mutableStateOf("Hello") // 내부에서만 사용하도록 외부 접근 금지
// mutableStateOf는 읽기와 쓰기 가능
val data: State<String> = _data // State 타입으로 정의해서 외부에서는 읽기전용으로 접근
fun changeValue() {
_data.value = "World"
}
}
💡ViewModel 과 Hoisting의 차이점
- hoisting은 부모-자식 관계에서 데이터와 상태를 공유하는 것에 적합
- viewModel은 보다 넓은 범위에서 사용하며 모든 컴포저블이 접근할 수 있음
🔥사진 출처 및 참고 자료
Android | Jetpack Compose State Hoisting
읽기 전 불필요한 코드나 잘못 작성된 내용에 대한 지적은 언제나 환영합니다. 개인적으로 실습하면서 배운 점을 정리한 글입니다, Jetpack Compose의 State 코드랩과 Jetpack Compose State 공식문서의 내
8iggy.tistory.com
https://www.youtube.com/watch?v=Fn_xJ_IRHiA&list=PLxTmPHxRH3VV8lJq8WSlBAhmV52O2Lu7n&index=10
'Android > Compose' 카테고리의 다른 글
NavController를 이용한 데이터 전달 (0) | 2023.10.26 |
---|---|
이미지를 포함한 Composable 화면 비트맵으로 저장 후 공유하기 (1) | 2023.10.24 |
State Remember & rememberSaveable (3) | 2023.10.24 |