Search code examples
javascriptreactjsreact-nativetabbar

Rerender different tabs in React Native


I am working on building a React Native app with a number of tabs. Each tab renders data that comes from an API call:

'use strict';

var React = require('react-native');
var {
  StyleSheet,
  TabBarIOS,
  Text,
  View,
  NavigatorIOS,
} = React;

// Load up tab pages
var Home = require('./Home');
var Appointments = require('./Appointments');
var Clients = require('./Clients');
var EmailMarketing = require('./EmailMarketing');
var Analytics = require('./Analytics');
var AddClient = require('./AddClient');

var Icon = require('react-native-vector-icons/Ionicons');

var TabBar = React.createClass({
  getInitialState() {
    return {
      selectedTab: 'home',
    };
  },
  render() {

      return (
        <TabBarIOS ref="tabBar" selectedTab={this.state.selectedTab}>
          <Icon.TabBarItem
            title="Home"
            selected={this.state.selectedTab === 'home'}
            iconName="ios-home-outline"
            selectedIconName="ios-home"
            onPress={() => {
              if (this.state.selectedTab !== 'home') {
                this.setState({
                  selectedTab: 'home'
                });
              } else if (this.state.selectedTab === 'home') {
                this.refs.homeRef.popToTop();
              }


            }}
            >
            <NavigatorIOS
              style={styles.container}
              ref='homeRef'
              initialRoute={{
                title: 'Home',
                component: Home
              }} />
          </Icon.TabBarItem>

          <Icon.TabBarItem
            title="Appointments"
            selected={this.state.selectedTab === 'appointments'}
            iconName="ios-calendar-outline"
            selectedIconName="ios-calendar"
            onPress={() => {
              if (this.state.selectedTab !== 'appointments') {
                this.setState({
                  selectedTab: 'appointments'
                });
              } else if (this.state.selectedTab === 'appointments') {
                this.refs.appointmentsRef.popToTop();
              }
            }}
            >
            <NavigatorIOS
              style={styles.container}
              ref='appointmentsRef'
              initialRoute={{
                title: 'Appointments',
                component: Appointments
              }} />
          </Icon.TabBarItem>

          <Icon.TabBarItem
            title="Clients"
            selected={this.state.selectedTab === 'clients'}
            iconName="ios-people-outline"
            selectedIconName="ios-people"
            onPress={() => {
              if (this.state.selectedTab !== 'clients') {
                this.setState({
                  selectedTab: 'clients'
                });
              } else if (this.state.selectedTab === 'clients') {
                this.refs.clientsRef.popToTop();
              }
            }}
            >
            <NavigatorIOS
              style={styles.container}
              ref='clientsRef'
              initialRoute={{
                rightButtonTitle: 'Add Client',
                onRightButtonPress: () => {
                  this.refs.clientsRef.navigator.push({
                    title: "Add Client",
                    component: AddClient
                  });
                },
                title: 'My Clients',
                component: Clients
              }} />
          </Icon.TabBarItem>

          <Icon.TabBarItem
            title="Email Marketing"
            selected={this.state.selectedTab === 'emailMarketing'}
            iconName="ios-email-outline"
            selectedIconName="ios-email"
            onPress={() => {
              if (this.state.selectedTab !== 'emailMarketing') {
                this.setState({
                  selectedTab: 'emailMarketing'
                });
              } else if (this.state.selectedTab === 'emailMarketing') {
                this.refs.emailMarketingRef.popToTop();
              }
            }}
            >
            <NavigatorIOS
              style={styles.container}
              ref='emailMarketingRef'
              initialRoute={{
                title: 'Email Marketer',
                component: EmailMarketing
              }} />
          </Icon.TabBarItem>

          <Icon.TabBarItem
            title="Analytics"
            selected={this.state.selectedTab === 'analytics'}
            iconName="ios-pie-outline"
            selectedIconName="ios-pie"
            onPress={() => {
              if (this.state.selectedTab !== 'analytics') {
                this.setState({
                  selectedTab: 'analytics'
                });
              } else if (this.state.selectedTab === 'analytics') {
                this.refs.analyticsRef.popToTop();
              }
            }}
            >
            <NavigatorIOS
              style={styles.container}
              ref='analyticsRef'
              initialRoute={{
                title: 'Analytics',
                component: Analytics
              }} />
          </Icon.TabBarItem>
        </TabBarIOS>
      );
    },
});


var styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    backgroundColor: '#123456',
  },
})



module.exports = TabBar;

The issue I'm having is that if a user decided to change or modify the data in one tab (e.g., if they add a 'client' to their list of clients) they should be able to see that change in the other tab as a result of the API call (e.g., in the index of clients). What I'm finding is that switching back and forth between the different tabs doesn't seem to trigger the state being rerendered and, therefore, the API being called again - as a result, it just shows stale data from the last API call. What is the best way to handle this?


Solution

  • You need some kind of shared state between your components. Try redux or some other flux implementation.