I have a question about recomposition in my compos...
# compose
b
I have a question about recomposition in my composable. Can you please tell me why my log message gets executed twice although no value has changed except the viewstate which is not referenced in the log message?
Copy code
fun ScreenHorizontalPager() {
  Timber.v("This log message gets executed twice")

  val screenViewModel = viewModel<ScreenViewModel>()
  screenViewModel.dispatch(action = KScreenLoadAction())
  
  // screenViewState starts with Loading and then switches to success or error
  val screenViewState by screenViewModel.state.collectAsState()
  
  when(screenViewState) {
  	is Loading -> ...
  	is Success -> ...
  	is Error -> ...
  }
}
r
If the state you are reading changes, why do you expect the log to not appear again?
b
@romainguy Because the state is read below the log message. But maybe my understanding of the recomposition is not correct. So if i am on the same "level" of the change all gets recomposed?
c
What you are seeing is explained by the concept of recomposition scopes. When your
screenViewState
changes the nearest scope gets recomposed. In this case it is your entire Composable function, not just the portion of it after the line where the state change happened. You can read more about recomposition scopes here: https://developer.android.com/develop/ui/compose/performance/bestpractices
b
@curioustechizen thx a lot for the link, but at the moment i get an internal server error. If i understand you correct my whole composable function gets recomposed. And what happens if i call another composable function in there which does not read the viewstate. Does this function also get called or will it be skipped?
s
If that other function only takes in stable parameters, and those parameters haven't changed, then yes it will skip. If it takes unstable parameters, then it will depend on if you got strong skipping mode enabled or not, and of those unstable parameters are the same instance or not.
But here you're doing two side effects straight in composition. Both the log and the dispatch should definitely be done inside an effect where you control the inputs. Perhaps a LaunchedEffect(Unit) is what you might want. Otherwise this dispatch and the log will very likely trigger multiple times for various reasons
f