Search code examples
javascriptreactjsreact-nativereact-navigationreact-state-management

How to clean up state in class component in React Native?


I'm a newbie in React Native and struggling in cleaning up the state of the screen.

Like screen A has some states --> screen B, back to screen A, old states are clear. I'm using React Navigation V5

What I'm trying to do is:

  1. After navigating from MainMap.js to the last screen TripsListScreen.js (the whole process is a Stack of 4 screens, nested in a Drawer), I got all the data stored in Redux's store, and display it in TripsListScreen.
  2. The problem is when I press the add button in TripsListScreen to comeback at the MainMap.js, it doesn't clean up every state as I expect.

Here's the MainMap.js 's states:

const initialState = {
    hasMapPermission: false,
    _userLocationDisplayed: null,
    userLatitude: 0,
    userLongitude: 0,
    initial_UserLatitude: 0,
    initial_UserLongitude: 0,
    userLocationAddress: '',

    destination: [],
    destinationName: [],
    destinationAddress: [],
    destinationCoords: [],
    destinationImageUri: [],

    numOfInput:[0,1],
    counter: 1,
    wayPoints: [],
    markers: [],
}

class MainMap extends React.Component{

    constructor(props){
        super(props);

        this.state = initialState;


    };


    componentDidMount(){
        console.log('Hello',this.props)
        if(this.props.route.params === true){
            this.setState(initialState)
        }
        this._requestUserLocation();
    };

Basically, I tried to pass a boolean param from TripsListScreen to MainMap, and if the param is true, I'll set all the states back to the beginning. However, it doesn't work as expected.

Here's TripsListScreen:

//...
<Layout style={styles.bottom}>
      <TouchableOpacity onPress={() => props.navigation.navigate('PlanningProcess', {
            screen: 'MainMapScreen',
            params: {doAddPlace: true}
      })} style={styles.createTrip}>
          <Layout style={styles.button} >
               <Icon name='add' size={35} />
          </Layout>
      </TouchableOpacity>
</Layout>
//...

Here's the Navigation:

  1. StackNavigators:
const Stack = createStackNavigator();

const StackNavigator = (props) => {
    return(
        <Stack.Navigator screenOptions={{headerShown: false}}>
            <Stack.Screen name='MainMapScreen' component={MainMap} />
            <Stack.Screen name='TripDescription' component={TripDescription} />
            <Stack.Screen name='TripsListDetailScreen' component={TripsListDetailScreen} />
            <Stack.Screen
                name='TripsListScreen' 
                component={TripsListScreen} 
                options={{
                    headerLeft: () => (<Icon style={{marginHorizontal: 30, marginTop: 30}} color='white' name='menu' size={30} onPress={() => props.navigation.dispatch(DrawerActions.openDrawer())}/>),
                    title:'Something'
                    }}
            />
        </Stack.Navigator>
    );
};
export default StackNavigator;
  1. Main Navigators:
const Navigator = () => {

    return(
        <NavigationContainer>
            <Drawer.Navigator
                statusBarAnimation='slide'
                drawerContent={props => 
                    <DrawerContent {...props} />}>
                <Drawer.Screen name='Welcome' component={WelcomeStackScreen}  />
                <Drawer.Screen name='TripsListScreen' component={TripsListScreen} />
                <Drawer.Screen name='PlanningProcess' component={StackNavigators} />
            </Drawer.Navigator>

        </NavigationContainer>
    );
};


export default Navigator;

This is what MainMap renders:

What MainMap renders

This is what I expected, when navigating from TripsListScreen ( to create a new trip):

Expected result after cleaning

PLEASE HELP !!!


Solution

  • The method ComponentDidMount() only triggers for the first time at the mounting of the component and as you are navigating to a new screen, the previous screen is still mounted in the stack.

    If you want to re-initialize your state every time your component gets the focus, you can set a listener on the focus on the navigation.

    Like this,

    const unsubscribe = navigation.addListener('willFocus', () => {
          // Do something 
          // re-initialise the state
    });