Reputation: 22457
I'am using Compose now with passing parameters to functions, but I feel, those parameters are getting longer with each new data to be passed down the tree.
I am wondering if there is a way to pass values to other composables down the tree.
Upvotes: 6
Views: 9479
Reputation: 22457
Other than using function arguments for Composables (the recommended way), you can use CompositionLocal: Avoid CompositionLocal for concepts that aren't thought as tree-scoped or sub-hierarchy scoped.
First, define variable of compositionLocalOf
globally (e.g., in LocalCompositions.kt):
import androidx.compose.runtime.compositionLocalOf
data class Post(val title: String)
val LocalPost = compositionLocalOf { Post(title = "Ahmed") }
and then define it inside @Compose
function to be used by other composables down the tree:
@Composable
fun MainView() {
...
val post = Post(title = "Shamil")
CompositionLocalProvider(LocalPost provides post) {
PostContentView()
}
...
}
Now, retrieve the value inside a @Composable
:
// composable down the nodes tree
@Composable
fun PostContentView() {
...
val post = LocalPost.current
...
}
If you want to achieve the above solution but with watching changes to the variable and update the composable (node) accordingly, you can use MutableState
variable.
Redefining the previous example:
LocalCompositions.kt:
import androidx.compose.runtime.compositionLocalOf
import androidx.compose.runtime.compositionLocalOf
import androidx.compose.runtime.mutableStateOf
data class Post(val title: MutableState<String> = mutableStateOf(""))
val LocalPost = compositionLocalOf { Post(title = mutableStateOf("Ahmed")) }
and then define it inside @Compose
function to be used by other composables down the tree:
@Composable
fun MainView() {
...
val post = Post(title = remember { mutableStateOf("Shamil") })
CompositionLocalProvider(LocalPost provides post) {
PostContentView()
}
...
post.title.value = "Ali"
...
}
Now, retrieve the value inside a @Composable
:
// composable down the nodes tree
@Composable
fun PostContentView() {
...
val post = LocalPost.current
// now this composable will be updated whenever post.title value is updated
if (post.title.value == "Jamal") {
...
}
...
}
Upvotes: 8