25

Here I'm using react-navigation as my navigation library.

How can I change the back button (that is added automatically by react-navigation) functionality for a specific screen?

I mean instead of going one step in the stack of screens I want it to go 2 steps back in stack or do it manually by giving the screen name (again only on one component).

greW
  • 1,248
  • 3
  • 24
  • 49
  • 1
    Possible duplicate of [Custom back navigation for reactnavigation back button](https://stackoverflow.com/questions/50074451/custom-back-navigation-for-reactnavigation-back-button) – Abanoub Istfanous Sep 09 '19 at 10:54

6 Answers6

41

Consider, that you have 3 screens A, B, C respectively. So, the default functionality of the back button in StackNavigator is:- If you press the Back Button on screen C, it will take you to the previous screen i.e, screen B. To override that you could do something like this on screen C:-

import { HeaderBackButton } from 'react-navigation';
static navigationOptions = ({navigation}) => {
  return{
    headerLeft:(<HeaderBackButton onPress={()=>{navigation.navigate('A')}}/>)
 }
}
Varun Gupta
  • 461
  • 1
  • 4
  • 5
  • 1
    Use `labelVisible={false}` and `tintColor={'#FFF'}` for more customization, All props in [here](https://github.com/react-navigation/stack/blob/64c14bb20a8cf1b0c060f3ee338528346bb59625/src/types.tsx#L161) – Sodj Jun 10 '20 at 15:35
  • I cant use static in my code saying = Declaration or statement expected.ts(1128) –  Jan 29 '21 at 05:58
  • 2
    With the latest version, it now needs to be imported from `@react-navigation/elements`: https://reactnavigation.org/docs/elements/#headerbackbutton – Daniel Jun 28 '23 at 03:49
21

You can override back button for a specific screen with navigationOptions of that screen. You can read more info about overriding back button in react-navigation docs

Example from docs

class HomeScreen extends React.Component {
  static navigationOptions = {
    headerTitle: <LogoTitle />,
    headerRight: (
      <Button
        onPress={() => alert('This is a button!')}
        title="Info"
        color="#fff"
      />
    ),
  };
}

Overriding the back button

The back button will be rendered automatically in a StackNavigator whenever it is possible for the user to go back from their current screen — in other words, the back button will be rendered whenever there is more than one screen in the stack.

Generally, this is what you want. But it's possible that in some circumstances that you want to customize the back button more than you can through the options mentioned above, in which case you can specify a headerLeft, just as we did with headerRight, and completely override the back button.

bennygenel
  • 23,896
  • 6
  • 65
  • 78
  • 4
    is there a way to change only the `onPress()` function ? I want to keep the initial back image – greW Mar 25 '18 at 16:33
  • @greW not directly I believe. But you can check the source code for navigation bar for react-native and see if you can import the same button they use for back and then override onPress prop. But I think using a custom button would be simpler. – bennygenel Mar 25 '18 at 16:37
  • 12
    thanks for the answer, I'll mark it as the answer as you helped me to achieve it. for whoever that needs that arrow you can simple Import that component and just override the the `onPress` prop. `import { HeaderBackButton } from 'react-navigation'` – greW Mar 25 '18 at 16:48
  • @greW you can edit my answer with the small example of how you used `HeaderBackButton` that would be perfect. – bennygenel Mar 25 '18 at 16:51
  • @greW is it possible to show alert box to get user conformation on HeaderBackButton before navigating to other screen – Pooja Jan 10 '21 at 04:13
  • What if I don't want to override the back button text for a specific screen, rather I just want to override the default 'Back' text? – Nermin Aug 10 '21 at 15:49
11

If you are on version 5, and are dealing with a functional component, you can use a layout effect hook to accomplish this (example from the docs reference):

function ProfileScreen({ navigation, route }) {
  const [value, onChangeText] = React.useState(route.params.title);

  React.useLayoutEffect(() => {
    navigation.setOptions({
      title: value === '' ? 'No title' : value,
    });
  }, [navigation, value]);

Note that if you are changing headerLeft, you may need to pass a function to it (GH issue reference).

twelve17
  • 688
  • 8
  • 20
9

By default, HeaderBackButton component is used. You can implement it and use it to override the back button styles, press props, for example: link to docs

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

const styles = StyleSheet.create({
  custom: {
  // Custom styles here
  }
});

<Screen
  name="Home"
  component={HomeScreen}
  options={{
    headerLeft: (props) => (
      <HeaderBackButton
        {...props}
        style={styles.custom}
        onPress={() => {
        // Do something
        }}
      />
    ),
  }}
/>;

If you want full control, you can use your custom back button component, example:

import { CustomBackButton } from 'path/to/custom/component';

<Screen
  name="Home"
  component={HomeScreen}
  options={{
    headerLeft: (props) => (
      <CustomBackButton {...props} />
    ),
  }}
/>;
Bogdan Kyrychuk
  • 269
  • 3
  • 7
  • This was helpful but I was getting "error check header render method" since I'm using version 6 I needed to also import react-navigation/elements per this [answer](https://stackoverflow.com/a/70109447/16743381) – Jacob Sherwood Mar 29 '22 at 15:31
7

You can do this while creating the stack navigator as well. Updated as of react-navigation v4.

import { createStackNavigator, HeaderBackButton } from "react-navigation-stack";

const yourStackNavigator = createStackNavigator({
  SomeRoute: SomeScreen,
  SpecificRoute: {
    screen: SpecificScreen,
    navigationOptions: ({ navigation }) => ({
        headerLeft: (<HeaderBackButton onPress={_ => navigation.navigate("Somewhere")}/>)
    })
  },
});
Rubek Joshi
  • 562
  • 7
  • 22
1

Short Way

You have A, B, C screens. You are currently A, after touch component you entered B. Now you are in screen B. In screen B your code can execute like under example:

// handling after back button event
navigation.pop();  // The B screen will delete
navigation.navigate("C");  // The C you are switching

Now you are in C. If you use back button you are going to go back to A.

Alternatively, we can use replace:

// handling after back button event
navigation.replace("C");  // The B screen will put out for C
Baris Senyerli
  • 642
  • 7
  • 13