Observing Kotlin Flow/StateFlow
Signatures:
fun <T> ComponentScope.useFlow(stateFlow: StateFlow<T>): Tfun <T> ComponentScope.useFlowWithLifecycle(stateFlow: StateFlow<T>, minActiveState: Lifecycle.State = RESUMED): T
| Hook | Lifecycle Aware | Auto-Pause |
|---|---|---|
useFlow | No | No |
useFlowWithLifecycle | Yes | Pauses below minActiveState |
Requirement: useFlowWithLifecycle requires LifecycleOwner via withLifecycleOwnerTreeProp
Import:
import com.facebook.litho.useFlow
import com.facebook.litho.useFlowWithLifecycle
Dependency: com.facebook.litho:litho-coroutines-kotlin
The useFlow hook enables Litho components to observe and react to Kotlin StateFlow emissions, automatically triggering re-renders when the flow emits new values.
This API is similar to Compose's collectAsStateWithLifecycle.
To familiarize yourself with the concept and rules for hooks, see the Introduction to Hooks page.
Basic Usage
The simplest form of useFlow takes a StateFlow and returns its current value. The component will automatically re-render whenever the flow emits a new value:
import com.facebook.litho.Component
import com.facebook.litho.ComponentScope
import com.facebook.litho.KComponent
import com.facebook.litho.kotlin.widget.Text
import com.facebook.litho.useFlow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
class UserStatusComponent(private val statusFlow: StateFlow<String>) : KComponent() {
override fun ComponentScope.render(): Component {
val status = useFlow(statusFlow)
return Text(text = "Status: $status")
}
}
The flow will be collected on the CoroutineScope provided by the component's tree prop, and collection will be automatically canceled when the component is detached from the tree.
Lifecycle-Aware Collection
For scenarios where you need to pause flow collection based on the lifecycle state (for example, to avoid unnecessary updates when the UI is not visible), use useFlowWithLifecycle:
import com.facebook.litho.Component
import com.facebook.litho.ComponentScope
import com.facebook.litho.KComponent
import com.facebook.litho.kotlin.widget.Text
import com.facebook.litho.useFlowWithLifecycle
import androidx.lifecycle.Lifecycle
import kotlinx.coroutines.flow.StateFlow
class LocationComponent(private val locationFlow: StateFlow<Location>) : KComponent() {
override fun ComponentScope.render(): Component {
val location = useFlowWithLifecycle(
stateFlow = locationFlow,
minActiveState = Lifecycle.State.STARTED
)
return Text(text = "Location: ${location.latitude}, ${location.longitude}")
}
}
With useFlowWithLifecycle, the flow collection is paused when the lifecycle falls below the specified minActiveState (which defaults to RESUMED) and resumes when the lifecycle returns to that state. Collection is completely canceled when the component is detached.
Integrating Litho with the LifecycleOwner
To use useFlowWithLifecycle, you must set the lifecycle owner using withLifecycleOwnerTreeProp when building the ComponentTree and pass the appropriate LifecycleOwner to it, or by calling setLifecycleOwnerTreeProp on LithoView. This can be done as shown in the sample below:
class LithoViewWithLifecycleOwnerFragment : Fragment() {
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?,
): View {
val componentContext = ComponentContext(requireContext())
// Create a ComponentTree with the lifecycle owner tree prop set
val componentTree =
ComponentTree.create(componentContext, LifecycleOwnerTreePropSampleComponent())
.withLifecycleOwnerTreeProp(this)
.enableChildClipping(true)
.build()
// Create a LithoView with the ComponentTree
val lithoView = LithoView(componentContext)
lithoView.componentTree = componentTree
return lithoView
}
}
Dependencies
In Gradle, you should add the following dependency to the build.gradle file:
dependencies {implementation 'com.facebook.litho:litho-coroutines-kotlin:0.50.2'}
See Also
- Introduction to Hooks - Hook fundamentals and rules
- useLiveData - Observe Android LiveData
- useState - Basic state management
- useEffect - Side effects and lifecycle