Keith
Keith

Reputation: 959

React Navigation params doesn't reset

I'm having trouble with resetting the navigation params to null in React Native.

MainTab
-- Home (stack)
-- Misc (stack)
-- Tips (stack)

On the Home tab, I have a button to go to Misc, but I want to route to the Tips tab on route to Misc.
Routing should look like - (Home -> Tips -> Misc)
That button returns the following with params -

this.props.navigation.navigate('Tips', {backRoute: 'Home', routeImGoingNext: 'Misc'});

When these params are passed, I render a back button and a skip button on the Tips screen's navigation based on the backRoute and routeImGoingNext params that were passed from the button on the Home tab.

if(navigation.state.params && navigation.state.params.backRoute){
  return {
    headerLeft: (<HeaderBackButton onPress={()=>navigation.navigate(navigation.state.params.backRoute)}/> ),
    headerRight: (
      <TouchableOpacity onPress={()=>navigation.navigate(navigation.state.params.routeImGoingnext)}>
        <Text style={{paddingRight: 10}}> Skip </Text>
      </TouchableOpacity>
    )
  }
}

My problem occurs when I click the Tips tab after I've already clicked the the button on the Home tab. The params are still set and therefore rendering a back button and skip button, but there shouldn't be those buttons if I click the Tips tab.

Any ideas on how to reset the params when you manually click on the tabs?

Upvotes: 16

Views: 41493

Answers (5)

In my case I had all screens in a Stack, therefore after I was done using the Route Params, I called navigate() to the same screen while explicitly setting all the params as null.

Upvotes: 0

user9371615
user9371615

Reputation: 67

This worked for me, straight from the documentation. Note that this resets the entire navigation state (props/routes/params etc...). In my case this was fine.

https://reactnavigation.org/docs/navigation-prop/

    props.navigation.reset({
        index: 0,
        routes: [{name: "Screen you need to go back to"}]
    });

My app is a simple 3 screen app in react native using react navigation "bottom tab navigator". All of my components are functional components so I did not use any sort of navigation-actions from this section of the docs: https://reactnavigation.org/docs/navigation-actions.

See my stack-navigation below. In the above code snippet, index: 0 would be the screen name "SetGame" below. index: 1 is "PlayGame" and index: 2 is "History". In my case I'm navigating back to index 0 which is "SetGame" and reseting routes/params/history in the navigation state object.

    <Tab.Navigator
  initialRouteName="Find"
  tabBarOptions={{
    tabStyle: {
      backgroundColor: '#76B947',
      height: 90,
      paddingBottom: 30,
      margin: 0,
    },
    style: {
      height: 90,
    },
    activeTintColor: '#292929',
    inactiveTintColor: '#ededed',

  }}
>
  <Tab.Screen
    name="SetGame"
    component={SetGame}
    options={{
      tabBarIcon: ({ color }) => (
        <Feather name={'list'} size={25} color={color} />
      ),
    }}
  />
  <Tab.Screen
    name="PlayGame"
    component={PlayGame}
    options={{
      tabBarIcon: ({ color }) => (
        <Feather name={'play'} size={25} color={color} />
      ),
    }}
  />
  <Tab.Screen
    name="History"
    component={GameHistory}
    options={{
      tabBarIcon: ({ color }) => (
        <Feather name={'save'} size={25} color={color} />
      ),
    }}
  />
</Tab.Navigator>

In my app inside of the PlayGame component there is a function to goBackToSetGame. Meaning we want to reset our game which clears data in the database and resets navigation state. Essentially disabling the user to play a game until it gets set again.

    const goBackToSetGame = async () => {
    const gameInputs = {
      email: user.profile.email,
      players: [],
      holes: [],
      names: [],
      createdAt: Date.now(),
      gameStatus: "not-playing",
      scores: [{}]
    }

    await API.QuitGame(gameInputs).then((res) => {
      // reset scores state if the game is quit
      setScores(null);
      console.log("Changed gameStatus from server response: ", 
    res.data)
    })
    .catch(err => console.log(err));

    // reset props.navigation so you have to 
    // start a new game before coming back to this screen
    props.navigation.reset({
      index: 0,
      routes: [{name: "SetGame"}]
    });
 }

Upvotes: 2

Stefan Morcodeanu
Stefan Morcodeanu

Reputation: 2158

I've also run into this issue and I found in documentation that params are shallow merged so if you have some prams from previous navigation and then you navigate to same screen with different params then they will be merged. Here is a link to documentation https://reactnavigation.org/docs/params Quick example will be:

navigation.navigate('Receipt', {id: '001', eventId: 'eventIdMock');

and from another screen, if I navigate to Receipt with this params:

navigation.navigate('Receipt', {id: '002'});

then the navigation will still have eventId: 'eventIdMock' so the solution is to set explicitly this value to null or undefined

navigation.navigate('Receipt', {id: '002', eventId: null});

enter image description here

Upvotes: 3

Mahdi Bashirpour
Mahdi Bashirpour

Reputation: 18823

Use this for clear params in react navigation

this.props.navigation.setParams({YOUR_PARAMS: null});

Upvotes: 15

Keith
Keith

Reputation: 959

I was able to clear the params by manually creating a function and setting the params that are passed to null. The clearParams function is called when the header button is pressed.

static navigationOptions = ({navigation}) => {

  clearParams = () => {
    navigation.setParams({backRoute: null, routeImGoingNext: null})
  }

  if(navigation.state.params && navigation.state.params.backRoute){  

    const { backRoute, routeImGoingNext } = navigation.state.params;

    return {
      headerLeft: (<HeaderBackButton onPress={()=>{navigation.navigate(backRoute), clearParams()}}/> ),
      headerRight: (
        <TouchableOpacity onPress={()=>{navigation.navigate(routeImGoingNext), clearParams() }}>
          <Text style={{paddingRight: 10}}> Skip </Text>
        </TouchableOpacity>
      )
    }
  }
 return;
}

Upvotes: 22

Related Questions