Adam Katz
Adam Katz

Reputation: 6962

React native, passing events from TabBarIOS through Navigator IOS

I have a react project which on the index.ios it has a navigator that looks like so..

          <TabBarIOS>

        <TabBarIOS.Item 
          title="example List" 
          selected={this.state.selectedTab === "example"}
          icon={require("./App/assets/sassiListIcon.png")}
          onPress={this.sassiHandleChange.bind(this)} >
          <View style={styles.main}>
            <example></example>
          </View>
        </TabBarIOS.Item>

        <TabBarIOS.Item 
          title="partners" 
          selected={this.state.selectedTab === "partners"}
          icon={require("./App/assets/partnersIcon.png")}
          onPress={this.partnersHandleChange.bind(this)} >
          <View style={styles.main}>
            <NavigatePartners></NavigatePartners>
          </View>
        </TabBarIOS.Item>

        <TabBarIOS.Item 
          title="About" 
          selected={this.state.selectedTab === "about"}
          icon={require("./App/assets/aboutIcon.png")}
          onPress={this.aboutHandleChange.bind(this)} >
          <View style={styles.main}>
            <About></About>
          </View>
        </TabBarIOS.Item>

      </TabBarIOS>

In the Partners tab it takes you to a NavigatorIOS which looks like so...

        return (
        <NavigatorIOS
      style={styles.mainContainer}
      initialRoute={{
        title: 'Partners',
        component: Partners,
        backButtonTitle: 'Back',
      }}/>

        )

Which then takes you to a page called partners and then to a page called partner.

Now when the Navigator is pressed, if the page is on partner, I want it to go back to Partners, but how do I register an even from the tab page and send it to the partner page? Thanks so much as always

Upvotes: 1

Views: 561

Answers (1)

Nader Dabit
Nader Dabit

Reputation: 53711

To pass a function from the Partners to the partner page ( a parent to a child ), you can do this the same way you pass any other property down, as a prop. When you are using the Navigator, you have to make sure you assign the passProps property to the navigator.

For example, if you had a function called alertClick, here is how you would pass it to another component with a navigator:

alertClick() {
    alert('clicked')
  },

  _handlePress() {
    this.props.navigator.push({
      id: 2,
      passProps: {
        alertClick: this.alertClick
      }
    });
  },

So, if you wanted to pass a function all the way down from the TabBar to the bottom child component, you could do it like so:

alertClick() {
  alert('clicked')
}

<TabBarIOS.Item 
      title="partners" 
      selected={this.state.selectedTab === "partners"}
      icon={require("./App/assets/partnersIcon.png")}
      onPress={this.partnersHandleChange.bind(this)} >
    <View style={styles.main}>
      <NavigatePartners alertClick={this.alertClick}></NavigatePartners>
    </View>
</TabBarIOS.Item>

// Then, in Partners

_handlePress() {
  this.props.navigator.push({
    id: 2,
    passProps: {
      alertClick: this.props.alertClick
    }
  });
},

// Then, in partner

<TouchableHighlight onPress={ this.props.alertClick } >

I've set up a full working example with the passProps assigned to the navigator and the function being passed down as well, without the TabBar here. Code is also below.

https://rnplay.org/apps/wKX_Dw

'use strict';
var React = require('react-native');
var {
  AppRegistry,
  StyleSheet,
  Text,
  View,
  Navigator,
  TouchableOpacity,
  TouchableHighlight
} = React;

var SCREEN_WIDTH = require('Dimensions').get('window').width;
var BaseConfig = Navigator.SceneConfigs.FloatFromRight;

var CustomLeftToRightGesture = Object.assign({}, BaseConfig.gestures.pop, {
  // Make it snap back really quickly after canceling pop
  snapVelocity: 8,
  // Make it so we can drag anywhere on the screen
  edgeHitWidth: SCREEN_WIDTH,
});

var CustomSceneConfig = Object.assign({}, BaseConfig, {
  // A very tighly wound spring will make this transition fast
  springTension: 100,
  springFriction: 1,
  // Use our custom gesture defined above
  gestures: {
    pop: CustomLeftToRightGesture,
  }
});

var PageOne = React.createClass({

  alertClick() {
    alert('clicked')
  },

  _handlePress() {
    this.props.navigator.push({
      id: 2,
      passProps: {
        alertClick: this.alertClick
      }
    });
  },

  render() {
    return (
      <View style={[styles.container, {backgroundColor: 'green'}]}>
        <Text style={styles.welcome}>Greetings!</Text>
        <TouchableOpacity onPress={this._handlePress}>
          <View style={{paddingVertical: 10, paddingHorizontal: 20, backgroundColor: 'black'}}>
            <Text style={styles.welcome}>Go to page two</Text>
          </View>
        </TouchableOpacity>
       </View>
    )
  },
});

var PageTwo = React.createClass({
  _handlePress() {
    this.props.navigator.pop();
  },

  render() {
    return (
      <View style={[styles.container, {backgroundColor: 'purple'}]}>
        <Text style={styles.welcome}>This is page two!</Text>
        <TouchableOpacity onPress={this._handlePress}>
          <View style={{paddingVertical: 10, paddingHorizontal: 20, backgroundColor: 'black'}}>
            <Text style={styles.welcome}>Go back</Text>
          </View>
            <TouchableHighlight underlayColor="orange" onPress={ this.props.alertClick } style={{ paddingLeft:10, paddingRight:10, height:60, flexDirection: 'row', alignItems: 'center', justifyContent: 'center', backgroundColor: 'orange', marginTop:20 }}>
                    <View>
                <Text style={{fontSize: 14}}>Function from parent</Text>
                      <Text style={{ fontSize: 22 }}>Click for alert</Text>
              </View>
            </TouchableHighlight>
        </TouchableOpacity>
       </View>
    )
  },
});

var SampleApp = React.createClass({
  _renderScene(route, navigator) {
    if (route.id === 1) {
      return React.createElement(PageOne, Object.assign({navigator}, {...route.passProps}))
    } else if (route.id === 2) {
      return React.createElement(PageTwo, Object.assign({navigator}, {...route.passProps}))
    }
  },

  _configureScene(route) {
    return CustomSceneConfig;
  },

  render() {
    return (
      <Navigator
        initialRoute={{id: 1, }}
        renderScene={this._renderScene}
        configureScene={this._configureScene} />
    );
  }
});

var styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
    backgroundColor: '#F5FCFF',
  },
  welcome: {
    fontSize: 20,
    textAlign: 'center',
    margin: 10,
    color: 'white',
  },
});

AppRegistry.registerComponent('SampleApp', () => SampleApp);

module.exports = SampleApp;

Upvotes: 2

Related Questions