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
ydidBlur
. 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.
- los
withNavigationFocus
componente de orden superior - los
<NavigationEvents />
componente - 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;