CompositionLocal: Implicitly Pass Data Down the UI Tree

CompositionLocal is like CSS inheritance for your UI tree, letting you pass data down implicitly without parameter drilling. It's ideal for ambient data like theming or localization. The footgun is overusing it, which makes components harder to test.
WHY IT EXISTS Passing data through many layers of composables just to reach one deeply nested component is tedious and clutters your function signatures. This problem, often called "prop drilling," makes code hard to refactor and reason about. CompositionLocal was created to provide a clean, scoped alternative for this specific scenario.
THE MENTAL MODEL Think of CompositionLocal like CSS inheritance. A parent element can define a font color, and all child elements inside it will automatically inherit that color without needing it explicitly set on each one. A CompositionLocalProvider sets a value for a part of the UI tree, and any composable within that tree can read that value implicitly.
HOW IT WORKS You first create a CompositionLocal using compositionLocalOf<Type>(), which acts as a key. You can provide a default value. Then, in your UI tree, you use a CompositionLocalProvider to supply a value for that key. Any composable function called within the provider's content lambda can access the provided value by using .current on the key. Composables that read the local will automatically recompose if the provided value changes.
WHEN TO USE IT Use it for ambient, semi-static data that needs to be accessed by many different composables in a subtree. The classic examples are theming data (MaterialTheme.colors is backed by a CompositionLocal), the current Android Context (LocalContext.current), or providing a singleton service like an analytics client to a specific screen flow.
WHEN NOT TO USE IT Do not use CompositionLocal as a general-purpose state management tool or a replacement for passing explicit parameters. If a composable's core job is to display a User object, that User should be an explicit parameter. Using a CompositionLocal for it makes the component's dependencies hidden, harder to test, and less reusable.
ONE CANONICAL EXAMPLE Accessing theme colors. The MaterialTheme composable wraps your app's content in a series of CompositionLocalProviders. This allows a Text composable, nested many layers deep, to access the primary color via MaterialTheme.colors.primary without you having to pass the colors object through every intermediate composable.
Read the original → developer.android.com
Get five bites like this every day.
Tezvyn delivers a daily feed of 60-second tech bites with quizzes to lock in what you learn.