[SOLVED] When recomposition happens exactly? with changing the state or also with changing the input

Issue

As far as I understood, each part of code which is related to any state will be changed(recomposed) with state changes →

And each state is an observable and the dependent UI part observes that state and is subscribed to it(the state) and whenever the state changes it will be notified(redrawing that part of UI) and happening recomposition.

But here in this article of google Thinking in compose, it says that recomposition happens with changing input, so I am confused.

Recomposition is the process of calling your composable functions again when inputs change. This happens when the function’s inputs change. When Compose recomposes based on new inputs, it only calls the functions or lambdas that might have changed, and skips the rest. By skipping all functions or lambdas that don’t have changed parameters, Compose can recompose efficiently.

Also, here in other sample of compose-roadmap, encourage hoisting the state to make the composable function stateless to avoid recompositions

So it would be great, if someone can make it clear that the recompositions happens only with state changes or input changes also causes?

Thank you in advance for your help

Solution

Recomposition happens when either the parameter values change or a mutable state variable within the composable function is updated.

A stateless function, sometimes referred to as an "immutable" function, is one where no data is stored in the function. This means that if you call the function repeatedly, it would be the same as if you had called it for the first time. The function retains no memory of any variables each time it is called.

Hoisting the state of a composable means that the state variables are kept outside of the composable and the values of those state variables are passed into the composable as normal parameters. This allows you to reuse the composable. This is especially important if you are creating a library of composables that you want to reuse from one project to another. Users of the library can be assured that there are no state dependencies that the composable requires. If you want a truely stateless composable, you would avoid doing things like passing in viewmodels. A viewmodel is very much dependent on the app in which it resides and will have code in it that is very specific to the app. A stateless composable has no dependencies on the app and therefore can be reused elsewhere.

That doesn’t mean that you can’t use viewmodels in your composables. Initially Google was against this when Compose first came out but realized that it was very awkward for developers. If a developer had no reason to make a reusable composable outside of the screen that it appears on, hoisting the state for every composable becomes a pain resulting in unnecessary boilerplate code. So the general rule is that if your composable is not going to be reused elsewhere and you need access to viewmodel data, you can either pass in the viewmodel as a parameter or access it within the composable through other means.

Aside from viewmodels, you may still want to make a composable stateful even when it needs to be reused. A good example of this is if you are using a TextField. As you are typing in text, you want the text to appear. Without using a state variable to retain the typed characters, you won’t see the TextField update. For this reason, using a local state variable to store the entered characters is acceptable. While this doesn’t make the composable stateless, it is still something you need to implement. However, even in this example, you can still make it stateless by passing the typed characters back up to the hoisted function and storing it in a viewmodel state variable that in turn triggers the hoisted function to recompose the composable and pass in the text that the TextField needs. But this is rather convoluted and a big round trip just to get characters shown in the TextField and therefore isn’t recommended. You might want to do it though if you have a very complex TextField composable and you need to process the characters in your viewmodel as they are being typed – such as might be the case for doing a suggestion lookup for a url.

So even if your composable is stateless but your viewmodel has a mutable state variable that the hoisted function is observing, if the mutable state of that variable changes, the hoisted function will recompose. But whether the composable that the hoisted composable is calling gets recomposed depends on whether the parameter values to that composable change. If they change, a recomposition will occur.

Answered By – Johann

Answer Checked By – David Goodson (BugsFixing Volunteer)

Leave a Reply

Your email address will not be published. Required fields are marked *