Somename
Somename

Reputation: 3444

Custom back navigation for reactnavigation back button

How can I give a custom navigation to the header back arrow in ReactNavigation? I want the back arrow in the header to navigate to the screen I define and not to the previous screen.

Thanks.

Upvotes: 16

Views: 28690

Answers (4)

MadeByRaymond
MadeByRaymond

Reputation: 1

You can also add a beforeRemove listener for when the current screen is about to be removed

navigation.addListener('beforeRemove', (e) => {
  if (everyThingIsGoodAlready) {
    // If we don't need to do anything, then just go back as usual
    return;
  }

  // Prevent default behavior of leaving the screen
  e.preventDefault();

  // Add any custom actions we need to take. E.g:
  // const customAction = () => {...}
  // customAction();


  /* 
    If you are all good and you want to continue with closing, 
    then you can dispatch the action you blocked earlier with e.preventDefault() 

    This will continue the action that had triggered the removal of the screen
  */
  navigation.dispatch(e.data.action);

})

Reference the official docs for more information and limitations to this method: https://reactnavigation.org/docs/preventing-going-back/

Upvotes: 0

IdleWork
IdleWork

Reputation: 21

The answer for React Navigation 6.x is as follows:

Use the HeaderBackButton from the @react-navigation/elements package.

import { HeaderBackButton } from '@react-navigation/elements';

const Main = () => {
  const navigation = useNavigation();

  // handle header left button press and navigate to desired screen
  const handlePress = useCallback(
    () => navigation.navigate('to the screen you desire'),
    []
  );

  // create header left button
  const headerLeft = useCallback(
    () => <HeaderBackButton onPress={handlePress} />,
    [handlePress],
  );

  // add header left button to the header
  useEffect(() => {
    navigation.setOptions({
      headerLeft,
    });
  }, [navigation, headerLeft]);

  // return what you want to show
  return null
}

Upvotes: 0

Gautam Naik
Gautam Naik

Reputation: 9376

You could try 2 things:

a) use headerMode: 'none' in your sub-StackRouters instead of your root router (named RouterComponent). Ideally you shouldn't have to do anything more then and the headers of the sub-StackRouters would be displayed in your root router's header. I think I remember something similarly worked a while back for me, but I haven't tested it in a while now and I think it's unlikely that it will still work like this but you can test nevertheless.

b) and this is what I'm currently using in a different situation. To manually include the back button:

import { HeaderBackButton } from '@react-navigation/stack';

const navigationOptions = ({ navigation }) => ({
    headerLeft: <HeaderBackButton onPress={() => navigation.goBack(null)} />,
})

const RouterComponent = StackNavigator({
    Tabs: {
        screen: Tabs
    },
    Profile: {
        screen: ProfileStack,
        navigationOptions
    }
},{
    mode: 'modal',
    headerMode: 'none',
});

If above solution doesn't work,

Try to add navigationOptions directly to the ProfileStack definition.

const ProfileStack = StackNavigator({
    ProfileHome: { 
      screen: ProfileHome, 
      navigationOptions: ({navigation}) => ({ //don't forget parentheses around the object notation
        title: 'Profile',
        headerLeft: <HeaderBackButton onPress={() => navigation.goBack(null)} />
      })
    },
    ProfileEdit: { screen: ProfileEdit }
  }

Upvotes: 23

Sukshith S
Sukshith S

Reputation: 501

Hi who ever is using react-navigation 5.x you might not be able to make navigation using navigationOptions. The option is been replaced with options.

Say your in screen -1 and navigated to screen-2 and then to screen-3. By default using react-navigation you can navigate from screen-3 to screen-2. But if you want customised navigation i.e., Say from above example if you want to navigate from screen-3 to screen-1.

If you would like to retain the view of back button and only override the onPress method, you can import { HeaderBackButton } from '@react-navigation/stack' and assign that component to the headerLeft option.

Example:

<RootStack.Screen
    name="dashboard"
    component={Dashboard}
    options={({navigation, route}) => ({
          headerLeft: (props) => (
            <HeaderBackButton
              {...props}
              onPress={() => navigation.navigate('Home')}
            />
          ),
     })}
  />

In above example on click of back button in Dashboard screen takes you to Home screen.

Enjoy & Thanks -Sukshith

Upvotes: 14

Related Questions