react-nativereact-navigationtabnavigator

How To Reload View Tap on TabNavigator in React Native


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',
  },
});

Solution

  • 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);
        },
      }),
    });