Compose

재사용 가능한 Composable 함수 만들기.

hik14 2024. 11. 5. 09:56

1. composable 함수는 기본적으로 빈 수정자(Modifier)가 할당되는 수정자 매개변수를 포함하는 것이 좋습니다.

@Composable
fun MyApp(modifier: Modifier = Modifier) {
 	...
}

 

함수 내에서 호출하는 첫 번째 컴포저블로 이 수정자를 전달합니다. 이렇게 하면 Caller가 composable 외부에서 레이아웃 안내와 동작을 조정할 수 있습니다.

@Composable
fun MyApp(modifier: Modifier = Modifier) {
    Surface(
        modifier = modifier,
       	.
        .
    ) {
       ....
    }
}

 

* 표준 레이아웃

 

2. Slot 기반 레이아웃 활용하기

 

슬롯 기반 레이아웃개발자가 원하는 대로 채울 수 있도록 UI에 빈 공간을 남겨 둡니다. 슬롯 기반 레이아웃을 사용하면 보다 유연한 레이아웃을 만들 수 있습니다.

@Composable
fun HomeSection(
   @StringRes title: Int,
   modifier: Modifier = Modifier,
   content: @Composable () -> Unit
) {
   Column(modifier) {
       Text(stringResource(title))
       content()
   }
}

@Preview(showBackground = true, backgroundColor = 0xFFF5F0EE)
@Composable
fun HomeSectionPreview() {
   MySootheTheme {
       HomeSection(R.string.align_your_body) {
           AlignYourBodyRow()
       }
   }
}

 

composable은 일반적으로 content composable lamda (content: @Composable () -> Unit)를 사용합니다. 

 

 

3. 적절한 State Hosting(상태 호이스팅)

 

remember를 사용하여 객체를 저장하는composable에는 내부 상태가 포함되며 이는 컴포저블을 스테이트풀(Stateful)로 만듭니다. 이는 호출자가 상태를 제어할 필요가 없고 상태를 직접 관리하지 않아도 상태를 사용할 수 있는 경우에 유용합니다. 그러나 내부 상태를 갖는 컴포저블은 재사용 가능성이 적고 테스트하기가 더 어려운 경향이 있습니다.

 

스테이트리스(Stateless) composable

- 상태를 소유하지 않는 컴포저블입니다. 즉, 새 상태를 보유하거나 정의하거나 수정하지 않습니다.

 

스테이트풀(Stateful) composable

- 시간이 지남에 따라 변할 수 있는 상태를 소유하는 컴포저블입니다.

- 실제 앱에서는 컴포저블의 기능에 따라 컴포저블을 100% 스테이트리스(Stateless)로 하는 것은 어려울 수 있습니다.

 

composable이 가능한 한 적게 상태를 소유하고, 적절한 경우 컴포저블의 API를 통해 상태를 노출하여 상태를 끌어올릴 수 있도록 컴포저블을 디자인해야 합니다.

 

어떻게 Stateful ==> Stateless 하게 할 수 있을까??

compose에서 State Hosting은 컴포저블을 스테이트리스(Stateless)로 만들기 위해 상태를 컴포저블의 호출자로 옮기는 패턴

 

Jetpack Compose에서 상태 호이스팅을 위한 일반적 패턴은 상태 변수를 다음 두 개의 매개변수로 바꾸는 것입니다.

  • value: T - 표시할 현재 값입니다.
  • onValueChange: (T) -> Unit - 값이 새 값 T로 변경되도록 요청하는 이벤트

* State Hosting 중요한 속성

  • 단일소스 저장소: 상태를 복제하는 대신 옮겼기 때문에 소스 저장소가 하나만 있습니다. 버그 방지에 도움이 됩니다.
  • 상태공유: 끌어올린 상태를 여러 컴포저블과 공유할 수 있습니다.
  • 이벤트가로채기 : 스테이트리스(Stateless) 컴포저블의 호출자는 상태를 변경하기 전에 이벤트를 무시할지 수정할지 결정가능
  • 분리/저장 가능: 구성 가능한 스테이트리스(Stateless) 함수의 상태는 어디에든(예: ViewModel) 저장할 수 있습니다.

그렇다면 무조건 상태를 끌어 올리는것이 좋은건가요???   NO.....

 

UI Tree의 최소 공통 조상까지 Hosting을 한다.

 

Hosting의 3가지 규칙.

  1. 상태는 적어도 그 상태를 사용하는 모든 컴포저블의 가장 낮은 공통 상위 요소로 끌어올려야 합니다(읽기).
  2. 상태는 최소한 변경될 수 있는 가장 높은 수준으로 끌어올려야 합니다(쓰기).
  3. 두 상태가 동일한 이벤트에 대한 응답으로 변경되는 경우 두 상태는 동일한 수준으로 끌어올려야 합니다.

이러한 규칙에서 요구하는 것보다 더 높은 수준으로 상태를 끌어올릴 수 있습니다. 하지만 상태를 충분히 높은 수준으로 끌어올리지 않으면 단방향 데이터 흐름을 따르기가 어렵거나 불가능할 수 있습니다.

 

4. NavigationController