I'm learning Jetpack Compose with an official tutorial that states:
It's a best practice to have your Composable accept a Modifier parameter, and pass that modifier to its first child.
And they provide examples where a @Composable
function uses the modifier
parameter given by its parent, chains new modifier elements to it, and passes that to its child components.
e.g:
@Composable
fun Greeting(name: String, modifier: Modifier = Modifier) {
Text(
text = "Hello $name!",
modifier = modifier.padding(bottom = 16.dp)
)
}
However, in a later exercise in the provided solution code, the modifier
parameter (with a lowercase m
) is mostly unused, and instead, a new instatiation of Modifier
(with an uppercase M
) is typically used.
What is actually the best practice? When do I use the modifier
parameter, and when do I create a new instantiation of Modifier
?
All composable functions that emit UI1 should take a parameter of type Modifier
as their first optional parameter. Optional means that it has a default value and therefore you do not need to pass such a parameter when you call the function.
Your example function contains the word modifier three times, each time meaning something different:
fun Greeting(name: String, modifier: Modifier = Modifier)
modifier
.Modifier
.Modifier
(which has, of course, also the type Modifier
). You could use any other Modifier object, but for the default value you shouldn't, it should always be the object that is named Modifier
, a global object that represents an empty modifier.Now, inside your composable you should use this modifier
parameter and apply it to the first UI element you use2. In your example that is the Text composable. It has a modifier parameter of its own that is declared identical to how your Greeting function declares it.
In your example, you not only pass your modifier
parameter to Text, you add another modifier first, effectively creating a modifier chain:
Text(
text = "Hello $name!",
modifier = modifier.padding(bottom = 16.dp)
)
But you could also simply pass the parameter through:
Text(
text = "Hello $name!",
modifier = modifier
)
(where the first word modifier is the parameter name of Text and the second is the actual modifier object that was passed to Greeting)
You could also use this (with a capital M
):
Text(
text = "Hello $name!",
modifier = Modifier
)
It compiles just fine, but now you do not use the modifier
parameter that was passed to Greeting anymore, you use the global Modifier
object. Since that is the same as the default value declared by Text you could omit it altogether:
Text(
text = "Hello $name!"
)
Conclusion: Use modifier
when you want to use the actual object that was passed to your function (it may contain any modifier or modifier chain). Use Modifier
when you want to access the global Modifier that is empty and doesn't actually modify anything. You mostly use it as a default value or as the starting point of a modifier chain.
1 That are composables like Column, Text, or most of the custom composables you will create, but not remember
and the likes; they are composable functions but they do not emit UI.
2 Only use it on the first element, do not use it on any other elements. For more See the official API Guidelines for @Composable
components in Jetpack Compose.