42

I am using a React-Navigation screen with the name "User" to show info about a particular user. When navigating to this route I pass the param "id" which tells the screen what user it is dealing with. When viewing a user it is possible to click something that will let you view another user.

At the moment this works and the new param makes the other user's details show up. The problem is that it does not navigate to a new screen for the other user and instead just changes the current screen. The problem is that when you navigate back it does not take you to the screen for the initial user but whatever was before it. You also get no visual cue that you navigated.

I would thus like to know how I can force it to navigate to another version of the same route.

If it makes any difference, I am working with Redux and navigate by dispatching generated actions like:

NavigationActions.navigate({ routeName: 'User', params: {userId} })
Gerharddc
  • 3,921
  • 8
  • 45
  • 83
  • @AbdulRauf I think the problem was that I was trying to navigate to a path that was just another tab inside a TabNavigator and if that TabNavigator was already open then it thought I just wanted to switch tabs. – Gerharddc Jun 25 '18 at 16:00

4 Answers4

72

You are looking for push instead of navigate. When you use navigate, it look for a route with that name, and if it exists navigate to it. When you use push, you go to a new route, adding a new navigation to the stack.

See the documentation here https://reactnavigation.org/docs/en/navigating.html#navigate-to-a-route-multiple-times

In your case, you should do:

NavigationActions.push({ routeName: 'User', params: {userId} }) 

or through your props (make sure your props has 'navigation'):

this.props.navigation.push('User', {userId:'paramValue'})
Adam
  • 3,815
  • 29
  • 24
tnemesis
  • 844
  • 1
  • 9
  • 8
  • 2
    Yes I already figured that out. Also note that StackActions provide more advanced actions including the option to reset stack which is very useful. https://reactnavigation.org/docs/en/stack-actions.html – Abdul Rauf Jun 25 '18 at 16:55
  • 2
    If there is a case where when you click back, I must be able to refresh the page with new data. For ex: I'm in user page and userId is 10, I pushed to user page again with user id 20, when I click back I want userid to be 10. How to achieve that ? – Vasanth Jul 23 '21 at 17:31
8

Use the navigation key to navigate to same route

const navigateAction = NavigationActions.navigate({
    routeName: 'User', 
    params: {userId},
    key: 'APage' + APageUUID
});

this.props.navigation.dispatch(navigateAction);

OR

this.props.navigation.navigate({
    routeName: 'User', 
    params: {userId},
    key: 'APage' + APageUUID
});

APageUUID is just a unique page id, can be generated with Math.random () * 10000

Reference

TalESid
  • 2,304
  • 1
  • 20
  • 41
4

Actually, the push function should be used instead of navigate:

import * as React from 'react';
import { Button, View, Text } from 'react-native';
import { NavigationContainer } from '@react-navigation/native';
import { createStackNavigator } from '@react-navigation/stack';

const HomeScreen = ({ navigation }) => (
  <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
    <Text>Home Screen</Text>
    <Button
      title="Go to Details"
      onPress={() => navigation.navigate('Details')}
    />
  </View>
);

const DetailsScreen = ({ navigation }) => (
  <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
    <Text>Details Screen</Text>
    <Button
      title="Go to Details... again"
      onPress={() => navigation.push('Details')} // push instead of navigate
    />
  </View>
);

const Stack = createStackNavigator();

const App = () => (
  <NavigationContainer>
    <Stack.Navigator initialRouteName="Home">
      <Stack.Screen name="Home" component={HomeScreen} />
      <Stack.Screen name="Details" component={DetailsScreen} />
    </Stack.Navigator>
  </NavigationContainer>
);

export default App;

Test it here

AmerllicA
  • 29,059
  • 15
  • 130
  • 154
1

This will reload the page with new data whenever the id changes.

 const [id , setId] = useState(props.route.params.id)

useEffect(() => {

        setId(props.route.params.id)

    }, [props.route.params?.id])

Put an onPress listener on the component while passing id or any props like..

 onPress={() => navigate(`yourComponentRouteName`, { id: _id })}
danklad
  • 88
  • 8