react-native componentWillUnmount not working while navigating

15,022

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.

Share:
15,022

Related videos on Youtube

Arunkumar K
Author by

Arunkumar K

Be Yourself

Updated on September 15, 2022

Comments

  • Arunkumar K
    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
    Arunkumar K about 6 years
    Yes i am using the stack navigator only, how can I close the old view while navigating to another ? is it possible
  • Rob Walker
    Rob Walker about 6 years
    If you are allowing users to swipe back or use the android back button, then you would want the view to be there.
  • Rob Walker
    Rob Walker about 6 years
    You 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
    Arunkumar K about 6 years
    Thank 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
    Shahzad about 6 years
    goback automatically unmount current screen and parent screen already unmounted so once you go back it will automatically refreshed on load(componentWillMount).
  • Shahzad
    Shahzad about 6 years
    he 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?