Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

184
Views
Evite que LaunchedEffect se vuelva a ejecutar en el cambio de configuración

Quiero ejecutar el código solo una vez cuando se carga el componible. Así que estoy usando LaunchedEffect con la clave como verdadera para lograr esto.

 LaunchedEffect(true) { // do API call }

Este código funciona bien, pero cada vez que hay algún cambio de configuración, como la rotación de la pantalla, este código se ejecuta nuevamente. ¿Cómo puedo evitar que vuelva a ejecutarse en caso de cambio de configuración?

over 4 years ago · Santiago Trujillo
3 answers
Answer question

0

La solución más simple es almacenar información sobre si realizó una llamada a la API con rememberSaveable : estará disponible cuando cambie la configuración.

 var initialApiCalled by rememberSaveable { mutableStateOf(false) } if (!initialApiCalled) { LaunchedEffect(Unit) { // do API call initialApiCalled = false } }

La desventaja de esta solución es que si la configuración cambia antes de que se complete la llamada a la API, la rutina LaunchedEffect se cancelará, al igual que su llamada a la API.

La solución más limpia es usar un modelo de vista y ejecutar la llamada API dentro de init :

 class ScreenViewModel: ViewModel() { init { viewModelScope.launch { // do API call } } } @Composable fun Screen(viewModel: ScreenViewModel = viewModel()) { }

La documentación oficial recomienda pasar el modelo de vista como este, como parámetro. En el código de producción, no necesita pasar ningún parámetro a esta vista, simplemente llámelo como Screen() : el modelo de vista se creará con el parámetro viewModel() predeterminado. Se mueve al parámetro para la capacidad de prueba/vista previa como se muestra en esta respuesta .

over 4 years ago · Santiago Trujillo Report

0

Supongo que la mejor manera es usar .also en la creación diferida de livedata/stateflow para garantizar que, mientras el modelo de vista esté activo, se llame a loadState solo una vez, y también garantice que no se llame al servicio en sí a menos que alguien lo está escuchando. Luego, escucha el estado desde el modelo de vista, y no es necesario llamar a nada api desde el efecto iniciado, también su código reaccionará al estado específico.

Aquí hay un ejemplo de código

 class MyViewModel : ViewModel() { private val uiScreenState: : MutableStateFlow<WhatEverState> = MutableStateFlow(WhatEverIntialState).also { loadState() } fun loadState(): StateFlow<WhatEverState>> { return users } private fun loadUsers() { // Do an asynchronous operation to fetch users. } }

Al usar este código, no tiene que llamar a loadstate en absoluto en la actividad, solo escucha al observador.

Puede consultar el siguiente código para escuchar

 class MyFragment : Fragment { override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View { return ComposeView(requireContext()).apply { setContent { StartingComposeTheme { Box(modifier = Modifier.fillMaxSize()) { val state by viewModel.uiScreenState.collectAsState() when (state) { //do something } } } } } }

}}

over 4 years ago · Santiago Trujillo Report

0

La respuesta de @ Islam Mansour funciona bien para el modelo de vista dedicado a la interfaz de usuario, pero mi caso es compartido por muchos fragmentos de interfaz de usuario.

En mi caso, las respuestas anteriores no resuelven mi problema para llamar a la API solo por primera vez cuando el usuario navega a la sección de IU en cuestión.

Porque tengo múltiples interfaces de usuario componibles en NavHost como fragmento

Y mi ViewModel a través de todos los fragmentos.

por lo tanto, la API solo debe llamar cuando el usuario navegue hasta el fragmento deseado

entonces, el siguiente inicializador de propiedades perezosas resuelve mi problema;

 val myDataList by lazy { Log.d("test","call only once when called from UI used inside)") loadDatatoThisList() mutableStateListOf<MyModel>() }

mutableStateListOf< LIST_TYPE > recompone automáticamente la interfaz de usuario cuando se agregan datos a este

variable copiada por by lazy inicializada solo una vez cuando se llama explícitamente

over 4 years ago · Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!