react-native componentWillUnmount not working while navigating
Solution 1
Routing to a new screen does not unmount the current screen.
For you usecase you instead of writing the code in componentWillUnmount you can continue by writing it after calling navigate in Details itself.
If you are looking for a callback when you press back from the new screen to come back to the current screen. Use goBack as shown in https://github.com/react-navigation/react-navigation/issues/733
Solution 2
If you are using a stack navigator, then routing to a new view loads the new view above the old one. The old view is still there for when you navigate back.
Solution 3
As I understand from your question and code you are using redux with navigation and want to unmount a screen. So what I did I just added a screen component inside another component to make my screen component as child.
e.g. below is the snippet that I am using to unmount the PushScreen
from PushedData
component.
I render PushScreen
and inside it there is component PushedData
that originally making the view. On PushedData
`componentWillMount I am just doing some conditional functionality and on success I am just unmounting PushData from PushScreen.
class PushScreen extends Component{
state ={ controllerLaunched: false };
updateControllerLauncher = () => {
this.setState({ controllerLaunched: true });
}
render (){
if(this.state.controllerLaunched){
return null;
} else {
return <PushedData handleControllerLauncher={this.updateControllerLauncher} />;
}
}
}
class PushedData extends Component{
componentWillMount(){
this.unmountPushData();//calling this method after some conditions.
}
unmountPushData = () => {
this.props.handleControllerLauncher();
}
render(){
return (
<View><Text>Component mounted</Text></View>
);
}
}
Let me know if you need more information.
Solution 4
If you want to go next Screen use (.replace instead .navigate) where you want to call componentWillUnmount. and if you want to go back to one of previous screens use .pop or .popToTop.
Solution 5
When you use Stack Navigator then routing to a new view loads the new view above the old one as Rob Walker said. There is a workaround. You can bind blur event listener on componentDidMount using navigation prop:
componentDidMount() {
this.props.navigation.addListener('blur', () => {
alert('screen changed');
})
}
So when your screen goes out of focus the event listener is called. You can find more about events right here.
Related videos on Youtube
Comments
-
Arunkumar K over 1 year
I am doing this simple steps but unmount was not calling I don't know why. Please I need a solution for this I need unmount to be get called while navigating to another screen...
class Homemain extends Component { constructor(props) { super(props); } componentWillMount(){ alert('willMount') } componentDidMount(){ alert('didMount') } componentWillUnmount(){ alert('unMount') } Details = () => { this.props.navigation.navigate('routedetailsheader') } render() { return( <View style={styles.container}> <TouchableOpacity onPress={() => this.Details()} style={{ flex: .45, justifyContent: 'center', alignItems: 'center', marginTop: '10%', marginRight: '10%' }}> <Image source={require('./../Asset/Images/child-notification.png')} style={{ flex: 1, height: height / 100 * 20, width: width / 100 * 20, resizeMode: 'contain' }} /> <Text style={{ flex: 0.5, justifyContent: 'center', fontSize: width / 100 * 4, fontStyle: 'italic', fontWeight: '400', color: '#000', paddingTop: 10 }}>Details</Text> </TouchableOpacity> </View> ); } } export default (Homemain);
This is my RouteConfiguration in this way I am navigating to the next screen. Can someone please help me for this error so that i can proceed to the next steps
import React, { Component } from 'react'; import PropTypes from 'prop-types'; import { addNavigationHelpers, NavigationActions } from 'react-navigation'; import { connect } from 'react-redux'; import { BackHandler } from 'react-native'; import { Stack } from './navigationConfiguration'; const getCurrentScreen = (navigationState) => { if (!navigationState) { return null } const route = navigationState.routes[navigationState.index] if (route.routes) { return getCurrentScreen(route) } return route.routeName } class StackNavigation extends Component { static propTypes = { dispatch: PropTypes.func.isRequired, navigation: PropTypes.shape().isRequired, }; constructor(props) { super(props); BackHandler.addEventListener('hardwareBackPress', this.backAction); } //backAction = () => this.navigator.props.navigation.goBack(); backAction = () => { const { dispatch, navigation } = this.props; const currentScreen = getCurrentScreen(navigation) if (currentScreen === 'Homemain') { return false } else if (currentScreen === 'Login') { return false } dispatch(NavigationActions.back()); return true; }; render() { const { dispatch, navigation } = this.props; return ( <Stack ref={(ref) => { this.navigator = ref; }} navigation={ addNavigationHelpers({ dispatch, state: navigation, }) } /> ); } } export default connect(state => ({ navigation: state.stack }))(StackNavigation);
-
Arunkumar K about 6 yearsYes i am using the stack navigator only, how can I close the old view while navigating to another ? is it possible
-
Rob Walker about 6 yearsIf you are allowing users to swipe back or use the android back button, then you would want the view to be there.
-
Rob Walker about 6 yearsYou should be able to look at the navigation object to inspect the current navigation location, then take some action based on that if you need to.
-
Arunkumar K about 6 yearsThank you for your time. Now I came to know how to unmount the component. Is it possible to refresh while we go back to the parent view?
-
Shahzad about 6 yearsgoback automatically unmount current screen and parent screen already unmounted so once you go back it will automatically refreshed on load(componentWillMount).
-
Shahzad about 6 yearshe is asking to unmount a component and you are telling him the screen will there in stack navigator then how come this could be the answer?