State hoisting 的例子

Kimoji:以 Jetpack Compose 實作一款「心情日記」應用 [13]

John Lu
Sep 15, 2022

此系列文章是以我的業餘專案: Kimoji 為範例。
這款以純 Jetpack Compose 撰寫的 side project,已經在 Google Play 上架。 歡迎試玩!
📥 立馬下載

在 Compose 當中,我們是不用隱藏 UI 元件的。只要我們不把這些元件加到 composition 裡就好,然後這些元件就不會加入 Compose 產生的 UI 樹狀結構了。只要使用簡單的 Kotlin 條件式邏輯就能達到這個效果。舉例來說,如果想顯示 onboarding 畫面,或日記本,我們可以這樣做:

但是,我們無法存取 shouldShowOnboarding。顯然我們需要和 KimojiApp composable 分享我們在 OnboardingScreen 建立的狀態。

我們不用想辦法把值分享給 parent,只要「hoist」就好,直接把值移動到需要存取的 common ancestor 裡面。

像是這樣:

我們還需要和 onboarding 畫面分享 shouldShowOnboarding,但是不必直接進行傳遞。我們可以不讓 OnboardingScreen 變更狀態,而是讓它通知我們使用者已經按下「Hi, Kimoji!」 按鈕,這樣的處理方式比較好。

如何向上傳遞事件呢?答案是向下傳遞 callbacks。Callbacks 是傳遞給其他函式當做參數的函式,在觸發事件時,就會執行這個函式。

我們來試著為 onboarding 畫面新增函式參數,定義為 onHiClicked: () -> Unit,以便變更 KimojiApp 裡的狀態。

解法:

藉由傳遞函式 (而不是 state) 給 OnboardingScreen,這個 composable 可以更容易被複用,也能保護 state 不會因為其他 composable 而變動。大致上來說,這個方法可以讓一切都簡潔許多。我們可以來看看現在如何修改 onboarding 的 preview 畫面來呼叫 OnboardingScreen

onHiClicked 指派給空白的 lambda 代表「什麼都不做」,這十分適合給預覽畫面使用。

此系列文章是以我的業餘專案: Kimoji 為範例

Kimoji 是一款心情日記 App,讓你用可愛的 emoji 來撰寫你的心情日記。現在就來試試這款設計精美的微日記吧!
📥 立馬下載

--

--

John Lu

Android Developer. Deeply motivated by challenges and tends to be excited by breaking conventional ways of thinking and doing. He builds fun and creative apps.