Saltar al contenido

La función `componentDidMount ()` no se llama después de la navegación

Solución:

Si alguien viene aquí en 2019, intente esto:

import {NavigationEvents} from 'react-navigation';

Agrega el componente a tu render:

<NavigationEvents onDidFocus={() => console.log('I am triggered')} />

Ahora, este evento onDidFocus se activará cada vez que la página se enfoque a pesar de venir de goBack () o navegar.

Si la sintaxis votada a favor que usa el componente NavigationEvents no funciona, puede probar con esto:

// no need to import anything more

// define a separate function to get triggered on focus
onFocusFunction = () => {
  // do some stuff on every screen focus
}

// add a focus listener onDidMount
async componentDidMount () {
  this.focusListener = this.props.navigation.addListener('didFocus', () => {
    this.onFocusFunction()
  })
}

// and don't forget to remove the listener
componentWillUnmount () {
  this.focusListener.remove()
}

La documentación de React-navigation describió explícitamente este caso:

Considere un navegador de pila con pantallas A y B. Después de navegar a A, se llama a su componentDidMount. Al presionar B, también se llama a su componentDidMount, pero A permanece montado en la pila y, por lo tanto, no se llama a su componentWillUnmount.

Al volver de B a A, se llama a componentWillUnmount de B, pero no a componentDidMount de A porque A permaneció montado todo el tiempo.

Ahora hay 3 soluciones para eso:

Suscripción a eventos del ciclo de vida

React Navigation emite eventos a los componentes de la pantalla que se suscriben. Hay cuatro eventos diferentes a los que puede suscribirse:
willFocus, willBlur, didFocus y didBlur. Lea más sobre ellos en la referencia de API.

Muchos de sus casos de uso pueden cubrirse con la withNavigationFocus
componente de orden superior, el <NavigationEvents /> componente, o el
useFocusState gancho.

  1. los withNavigationFocus
    componente de orden superior
  2. los <NavigationEvents />
    componente
  3. el gancho useFocusState (obsoleto)

withNavigationFocus

componente de orden superior

import React from 'react';
import { Text } from 'react-native';
import { withNavigationFocus } from 'react-navigation';

class FocusStateLabel extends React.Component {
  render() {
    return <Text>{this.props.isFocused ? 'Focused' : 'Not focused'}</Text>;
  }
}

// withNavigationFocus returns a component that wraps FocusStateLabel and passes
// in the navigation prop
export default withNavigationFocus(FocusStateLabel);

<NavigationEvents /> componente

import React from 'react';
import { View } from 'react-native';
import { NavigationEvents } from 'react-navigation';

const MyScreen = () => (
  <View>
    <NavigationEvents
      onWillFocus={payload => console.log('will focus', payload)}
      onDidFocus={payload => console.log('did focus', payload)}
      onWillBlur={payload => console.log('will blur', payload)}
      onDidBlur={payload => console.log('did blur', payload)}
    />
    {/*
      Your view code
    */}
  </View>
);

export default MyScreen;

useFocusState gancho

Primera instalación de la biblioteca yarn add react-navigation-hooks

import { useNavigation, useNavigationParam, ... } from 'react-navigation-hooks'

function MyScreen() {   const focusState = useFocusState();   return <Text>{focusState.isFocused ? 'Focused' : 'Not Focused'}</Text>; }

Aquí está mi solución personal, usando onDidFocus() y onWillFocus() para renderizar solo cuando los datos se hayan obtenido de su API:

import React, { PureComponent } from "react";
import { View } from "react-native";
import { NavigationEvents } from "react-navigation";

class MyScreen extends PureComponent {
  state = {
    loading: true
  };

  componentDidMount() {
    this._doApiCall();
  }

  _doApiCall = () => {
    myApiCall().then(() => {
      /* Do whatever you need */
    }).finally(() => this.setState({loading: false}));
  };

  render() {
    return (
      <View>
        <NavigationEvents 
              onDidFocus={this._doApiCall} 
              onWillFocus={() => this.setState({loading: true})}
        />
        {!this.state.loading && /*
        Your view code
        */}
      </View>
    );
  }
}

export default MyScreen;
¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *