How To Reload View Tap on TabNavigator in React Native

20,707

Solution 1

There's many long discussion about this from react-native issue 314, 486, 1335, and finally we got a way to handle this, after Sep 27, 2017, react-navigation version v1.0.0-beta.13:

New Features

Accept a tabBarOnPress param (#1335) - @cooperka

So here we go,

Usage:

const MyTabs = TabNavigator({
  ...
}, {
  tabBarComponent: TabBarBottom /* or TabBarTop */,
  tabBarPosition: 'bottom' /* or 'top' */,
  navigationOptions: ({ navigation }) => ({
    tabBarOnPress: (scene, jumpToIndex) => {
      console.log('onPress:', scene.route);
      jumpToIndex(scene.index);
    },
  }),
});

Solution 2

look at this link. My problem is solving thanks to this.

<Tabs.Navigator
    initialRouteName="Home"
    tabBar={(props) => (
       <TabBar {...props} />
    )}>
    <Tabs.Screen
      name="Home"
      component={HomeView}
      options={{ unmountOnBlur: true }}
      listeners={({ navigation }) => ({
        blur: () => navigation.setParams({ screen: undefined }),
      })}
    />
  </Tabs.Navigator>

https://github.com/react-navigation/react-navigation/issues/6915#issuecomment-692761324

Solution 3

I wasn't able to get this to work, and after checking the React Navigation documentation, found this, which seems to suggest that later versions (I'm using 1.0.0-beta.27) changed the method signature to a single object:

tabBarOnPress Callback to handle tap events; the argument is an object containing:

the previousScene: { route, index } which is the scene we are leaving

the scene: { route, index } that was tapped

the jumpToIndex method that can perform the navigation for you

https://reactnavigation.org/docs/en/tab-navigator.html#tabbaronpress

Given that, and the code from beausmith here, I put this together.

navigationOptions: ({ navigation }) => ({
    tabBarOnPress: (args) => {
        if (args.scene.focused) { // if tab currently focused tab
        if (args.scene.route.index !== 0) { // if not on first screen of the StackNavigator in focused tab.
            navigation.dispatch(NavigationActions.reset({
            index: 0,
            actions: [
                NavigationActions.navigate({ routeName: args.scene.route.routes[0].routeName }) // go to first screen of the StackNavigator
            ]
            }))
        }
        } else {
            args.jumpToIndex(args.scene.index) // go to another tab (the default behavior)
        }
    }
})

Note that you'll need to import NavigationActions from react-navigation for this to work.

Hope this helps somebody :)

Share:
20,707
Kirit Modi
Author by

Kirit Modi

Skype: kirit.modii SwiftUI React Native App SunClubRewards: https://play.google.com/store/apps/details?id=com.sunclubrewards&amp;hl=de Election 2019 App : https://play.google.com/store/apps/details?id=com.election2019 Swift Blog http://iosdevcenters.blogspot.com/

Updated on July 22, 2022

Comments

  • Kirit Modi
    Kirit Modi almost 2 years

    I want to reload the tabNavigator when the user changse the tab each time. the lifecycle method of react native doesn't get called when user changes the tab. Then how can it be possible to reload tab in TabNavigator :

    The below example have two Tabs : 1) Home 2)Events. Now I want to refresh the event Tab when user returns from the home tab.

    EXPO LINK : Expo Tab Navigator

    Code :

    import React, {Component} from 'react';
    import  {View, StyleSheet, Image, FlatList, ScrollView, Dimensions } from 'react-native';
    import { Button, List, ListItem, Card  } from 'react-native-elements' // 0.15.0
    //import { Constants } from 'expo';
    import { TabNavigator, StackNavigator } from 'react-navigation'; // 1.0.0-beta.11
    
    //image screen width and height defs
    const windowWidth = Dimensions.get('window').width;
    const windowHeight = Dimensions.get('window').height;
    
    
    export default class App extends Component {
      render() {
        //const { navigate } = this.props.navigation;
        return (
          <TabsNav  />
          )
      }
      }
    
    
    class MyHomeScreen extends Component {
      render() {
        return (
          <View>
                <Image
                  resizeMode="cover"
                  style={{    width: windowWidth * .85,    height: windowHeight * 0.3}}
                  source={{uri: 'http://www.ajaxlibrary.ca/sites/default/files/media/logo.png?s358127d1501607090'}}
                />
                <Button
                  onPress={() => this.props.navigation.navigate('Notifications')}
                  title="Go to notifications"
                />
          </View>
    
        );
      }
    }
    
    class AplEvents extends Component {
      static navigationOptions = {
        tabBarLabel: 'Events List',
        tabBarIcon: ({ tintColor }) => (
          <Image
            source={{uri: 'https://facebook.github.io/react/img/logo_og.png'}}
            style={[styles.icon, {tintColor: tintColor}]}
          />
        ),
      };
    
        constructor(props) {
        super(props);
    
        this.state = {
          data: [],
          error: null,
        };
      }
    
      // when component mounts run the function fetch
      componentDidMount() {
        this.makeRemoteRequest();
      }
    
      makeRemoteRequest = () => {
        const url = `http://www.ajaxlibrary.ca/?q=calendar-test`;
    
        fetch(url)
          .then((res) => res.json())
          .then((res) => {
            this.setState({
              data: [...this.state.data, ...res.nodes],
              error: res.error || null,
            });
          })
          .catch(error => {
            this.setState( error );
          });
      };
    
    
      render() {
        const { navigate } = this.props.navigation;
        return (
             <List containerStyle={{ marginTop: 0, borderTopWidth: 0, borderBottomWidth: 0 }}>
            <FlatList
              data={this.state.data}
              renderItem={({ item }) => (
                <ListItem
                  //squareAvatar
                  title={`${item.node.title}\n${item.node.Program_Location}`}
                  subtitle={item.node.Next_Session}
                  avatar={{ uri: item.node.Image }}
                  containerStyle={{ borderBottomWidth: 0 }}
                 // save params to pass to detailed events screen
                  onPress={() => navigate('Details', {title: `${item.node.title}`,
                                                    body: `${item.node.Body}`,
                                                    date: `${item.node.Date}`,
                                                    Next_Session: `${item.node.Next_Session}`,
                                                    Program_Location: `${item.node.Program_Location}`,
                                                    Nid: `${item.node.Nid}`,
                                                    Image: `${item.node.Image}`,
                                                    Run_Time: `${item.node.Run_Time}`})}
                />
              )}
              keyExtractor={item => item.node.Nid}
            />
            </List>
        );
      }
    }
    
    class EventDetails extends Component {
          static navigationOptions = {
        title: 'EventDetails'
      };
      render() {
        const { params } = this.props.navigation.state;
    
        let pic = {
          uri: `${params.Image}`
        };
        //const pic = { params.Image };
        return (
    
              <ScrollView>
    
                  <Card
                    title={params.title}
                  >
                      <Image
                          resizeMode="cover"
                           style={{    width: windowWidth * .85,    height: windowHeight * 0.3}}
                          source={pic}
                      />
    
                      <Button style={{marginTop: 10}}
                          icon={{name: 'date-range'}}
                          backgroundColor='#03A9F4'
                          fontFamily='Lato'
                          buttonStyle={{borderRadius: 0, marginLeft: 0, marginRight: 0, marginBottom: 0}}
                          title='Add to Calendar'
                      />
                        <ListItem
                         title="Event Description"
                         subtitle={params.body}
                         hideChevron='true'
                        />
                        <ListItem
                         title="Date"
                         subtitle={`${params.Next_Session}\n Run Time - ${params.Run_Time}`}
                         hideChevron='true'
                        />
                        <ListItem
                         title="Location"
                         subtitle={params.Program_Location}
                         hideChevron='true'
                        />
                  </Card>
              </ScrollView>
        );
      }
    }
    
    
    const styles = StyleSheet.create({
      icon: {
        width: 26,
        height: 26,
      },
    });
    
    const EventStack = StackNavigator({
        EventList: {
            screen: AplEvents,
              navigationOptions: {
                title: "APL Event Listing",
              }
        },
        Details: {
            screen: EventDetails,
        },
      TabsNav: { screen: MyHomeScreen}
      });
    
    const TabsNav = TabNavigator({
      Home: {
        screen: MyHomeScreen,
            navigationOptions: {
                tabBarLabel: 'Home',
                     tabBarIcon: ({ tintColor }) => (
                    <Image
                        source={{uri: 'https://upload.wikimedia.org/wikipedia/de/thumb/9/9f/Twitter_bird_logo_2012.svg/154px-Twitter_bird_logo_2012.svg.png'}}
                        style={[styles.icon, {tintColor: tintColor}]}
                    />
                    ),
            },
      },
      EventList: {
        screen: EventStack,
                navigationOptions: {
                tabBarLabel: 'Events',
                     tabBarIcon: ({ tintColor }) => (
                    <Image
                        source={{uri: 'https://upload.wikimedia.org/wikipedia/de/thumb/9/9f/Twitter_bird_logo_2012.svg/154px-Twitter_bird_logo_2012.svg.png'}}
                        style={[styles.icon, {tintColor: tintColor}]}
                    />
                    ),
            },
      },
    }, {
      tabBarOptions: {
        activeTintColor: '#e91e63',
      },
    });