Skip to main content

Props in Specs

caution

This page covers the old Java Spec API. If the Spec API is not being used, refer to the Components page.

Litho uses a unidirectional data flow with immutable inputs. Following the name established by React, inputs to a Component are known as props.

In the Spec API, props for a given Component are the union of all arguments annotated with @Prop. The value of the props can be accessed in all the methods that declare it as a @Prop parameter. The same prop can be defined and accessed in multiple lifecycle methods. The annotation processor will ensure you're using consistent prop types and consistent annotation parameters across all the spec methods.

In the Kotlin API, props are just val properties on a Component and can be accessed in the render function and its hooks.

Prop immutability​

The props of a Component are read-only. The Component's parent passes down values for the props when it creates the Component, and they cannot change throughout the lifecycle of the Component. If the props values must be updated, the parent has to create a new Component and pass down new values for the props.

info

Props should be immutable. Due to background layout, props may be accessed on multiple threads. The immutability of props ensures that no thread safety issues can occur during the component's lifecycle.

How to use Props​

Define Props on a Component​

The way props are defined is shown in the following sample:

Props are just val properties of a Component.

class HelloComponent(private val name: String) : KComponent() {

override fun ComponentScope.render(): Component {
return Text(text = "Hello $name!")
}
}

The props parameters will hold the value passed down from the Component's parent when the Component was created (or their default values).

Props are defined and used the same way as in LayoutSpecs and MountSpecs.

Set Props on a Component​

The following code shows how to set Props on a Component.

The prop can be passed by its name in the KComponent.

KotlinApiComponent(name = "Linda")

Optional Props and Prop Defaults​

Litho provides a way to mark props as optional and define their default values:

In the Kotlin API, default values are always explicit because optional props are just normal constructor params with default arguments.

class PropDefaultKComponent(private val name: String = "John Doe") : KComponent() {

override fun ComponentScope.render(): Component {
return Text(text = "Hello $name!")
}
}

Android Resources as Props​

When creating layouts, it's common to use values from Android's resource system, such as dimensions, colours, strings, and so on. The Litho Spec API provides convenient ways to set prop values from Android resources using annotations, as shown in the following examples:

Here, PropWithoutResourceTypeKComponent is expected to take color as an integer, size in pixels, and a name string.

class PropWithoutResourceTypeKComponent(
private val name: CharSequence,
private val size: Dimen,
@ColorInt private val color: Int
) : KComponent() {

override fun ComponentScope.render(): Component {
return Text(text = "Hello $name!", textSize = size, textColor = color)
}
}

If the props are to be set using resource values, it's recommended to do the following:

val res: Resources = context.getResources()
return PropWithoutResourceTypeKComponent(
name = res.getString(R.string.name_string),
size = dimenRes(R.dimen.primary_text_size),
color = ContextCompat.getColor(context.getAndroidContext(), R.color.primaryColor))

But Litho provides a nicer way to provide prop values via resource ids.

In the Kotlin API, there is no way to generate multiple variants of the same setter for a prop. However, helper functions can be used to retrieve the value of a resource by its ID, for example stringRes(), dimenRes(), colorRes(), colorAttr, and so on.

return PropWithResourceTypeKComponent(
name = stringRes(R.string.name_string),
size = dimenRes(R.dimen.primary_text_size),
color = colorRes(R.color.primaryColor))

Other supported functions are drawableRes(), drawableAttr(), drawableColor(), colorAttr() and intRes(). These can be found in the code under Resources

Variable Arguments in Props​

Sometimes, passing a list of items can be a bit painful as it requires the Developer to create a list structure, add all the items to it, then pass the list to the Component:

In the Kotlin API, use the variable number of arguments (varargs) modifier provided by the language itself to achieve this behaviour.

class VariableArgumentPropKComponent(private vararg val names: String) : KComponent() {

override fun ComponentScope.render(): Component {
return Column() {
for (name in names) {
child(Text(text = name, textSize = 16.sp))
}
}
}
}

It can then be used as follows:

return VariableArgumentPropKComponent("One", "Two", "Three", "Four")

Variable Arguments also work with Android resources as props:

In Kotlin, variable arguments can be used with Android resources by using the helper functions to resolve the value by resource ID. The following example shows how to provide multiple strings as props, mixing String variables and Android string resources:

return VariableArgumentPropKComponent(
"One", stringRes(R.string.app_name), stringRes(R.string.name_string))