Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

189
Visualizações
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 Respostas
Responde à pergunta

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 Relatório

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 Relatório

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 Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda