SearchBar: adopt outside text changes in a side effect
SearchBar keeps a TextFieldValue so that the cursor ends up behind text that was changed from the outside (a search started by typing on a physical keyboard, or a reset search). That value was updated during composition, which is an anti-pattern: the value read earlier in the same composition is what gets drawn, so the write only schedules another recomposition pass of the search bar - and it can be dropped entirely if the composition does not complete. Do the same update in a SideEffect, after the composition. No behaviour change for the user.
This commit is contained in:
@@ -24,6 +24,7 @@ import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.CompositionLocalProvider
|
||||
import androidx.compose.runtime.SideEffect
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
@@ -143,8 +144,14 @@ fun SearchBar(
|
||||
val textFieldValue = remember {
|
||||
mutableStateOf(TextFieldValue(value, TextRange(value.length)))
|
||||
}
|
||||
if (textFieldValue.value.text != value) {
|
||||
textFieldValue.value = TextFieldValue(value, TextRange(value.length))
|
||||
// Characters the user typed are already in this value; onValueChange below keeps the cursor
|
||||
// where the user put it. Text that changed from the outside - the search was reset, or a
|
||||
// character was inserted by the physical keyboard handler - is adopted here, with the cursor at
|
||||
// the end. This must not write state during composition, so it runs in a side effect after it.
|
||||
SideEffect {
|
||||
if (textFieldValue.value.text != value) {
|
||||
textFieldValue.value = TextFieldValue(value, TextRange(value.length))
|
||||
}
|
||||
}
|
||||
|
||||
LauncherCard(
|
||||
|
||||
Reference in New Issue
Block a user