javascript - React-native:将场景绑定(bind)到 NavigationBar

标签 javascript react-native navigator

我正在组装这个问答应用程序,遇到了这个障碍:

我想从导航栏触发场景中的功能。与登录应用类似,我在 NavigationBar 中有一个用于提交答案的按钮:

RightButton(route, navigator, index, navState) {
    if (route.name=='TextInputView'){
     return <TouchableHighlight
             underlayColor="transparent"
             style={{ marginRight:13,  marginTop:0}}
             onPress={() => this.refs.TextInputView.submitSolution()}>
        <Text style={ styles.leftNavButtonText }>Done</Text>
      </TouchableHighlight>
    }

renderscene(route,navigator) 看起来像这样:

if (route.name == 'TextInputView'){
  return <TextInputView ref="TextInputView" navigator={navigator} {...route.passProps}/>
}

当然在“TextInputView”组件中我有一个“submitSolution”函数...

问题是如果我在现场并按下“完成”——我总是得到: "undefined 不是对象(正在评估'_this2.refs.TextInputView')

一如既往:感谢您的帮助

最佳答案

好吧,您可以通过在场景本身中保留与提交相关的所有内容来做到这一点。

如何?

您可以通过按需在导航栏中插入一个按钮来实现。

这是我为我正在从事的项目创建的解决方案: https://rnplay.org/apps/dS31zw

我们的想法是为导航栏路由提供一个具有标签和功能的对象(以及您喜欢的任何东西......例如图标。)

作为奖励,您也可以插入标题!

注意:此技巧取决于在 NavigationBarRouteMapper 起作用之前调用 componentWillMount()。日后若有此变,必将破之。但它现在可以完美地工作了!

'use strict';

import React, {Component} from 'react';
import ReactNative from 'react-native';

const {
  AppRegistry,
  StyleSheet,
  Text,
  View,
  Navigator,
  Alert,
  TouchableHighlight
} = ReactNative;

class Home extends Component {

  //This trick depends on that componentWillMount fires before the navbar is created
  componentWillMount() {
        this.props.route.navbarTitle = "Home";

        this.props.route.rightNavButton = {
            text: "Button",
            onPress: this._doSomething.bind(this)
        };
    }

  _doSomething() {
    Alert.alert(
      'Awesome, eh?',
      null,
      [
        {text: 'Indeed'},
      ]
    )
  }

  render() {
    return (
      <View style={styles.container}>
            <Text>You are home</Text>
        </View>
    );
  }
}

class AppContainer extends Component {

    renderScene(route, navigator) {
        switch(route.name) {
            case "Home":
      //You must pass route as a prop for this trick to work properly
            return <Home route={route} navigator={navigator} {...route.passProps}  />
            default:
            return (
        <Text route={route}
        style={styles.container}>
            Your route name is probably incorrect {JSON.stringify(route)}
            </Text>
      );
        }
    }

  render() {
    return (
      <Navigator
        navigationBar={
          <Navigator.NavigationBar
            style={ styles.navbar }
            routeMapper={ NavigationBarRouteMapper } />
        }

        initialRoute={{ name: 'Home' }}
        renderScene={ this.renderScene }

      />
    );
  }
}

//Nothing fancy here, except for checking for injected buttons.
var NavigationBarRouteMapper = {
  LeftButton(route, navigator, index, navState) {
    if(route.leftNavButton) {
      return (
        <TouchableHighlight
        style={styles.leftNavButton}
        underlayColor="transparent"
        onPress={route.leftNavButton.onPress}>
          <Text style={styles.navbarButtonText}>{route.leftNavButton.text}</Text>
        </TouchableHighlight>
      );
    }
    else if(route.enableBackButton) {
      return (
        <TouchableHighlight
        style={styles.leftNavButton}
        underlayColor="transparent"
        onPress={() => navigator.pop() }>
          <Text style={styles.navbarButtonText}>Back</Text>
        </TouchableHighlight>
      );
    }
  },
  RightButton(route, navigator, index, navState) {
    if(route.rightNavButton) {
      return (
        <TouchableHighlight
        style={styles.rightNavButton}
        underlayColor="transparent"
        onPress={route.rightNavButton.onPress}>
          <Text style={styles.navbarButtonText}>{route.rightNavButton.text}</Text>
        </TouchableHighlight>
      );
    }
  },
  Title(route, navigator, index, navState) {
    return (<Text style={styles.navbarTitle}>{route.navbarTitle || route.name}</Text>);
  }
};

var styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
    backgroundColor: '#F5FCFF',
    marginTop: 66
  },
  navbar: {
    backgroundColor: '#ffffff',
  },
  navbarTitle: {
    marginVertical: 10,
    fontSize: 17
  },
  leftNavButton: {
    marginVertical: 10,
    paddingLeft: 8,
 },
  rightNavButton: {
    marginVertical: 10,
    paddingRight: 8,
  },
  navbarButtonText: {
    fontSize: 17,
    color: "#007AFF"
  }
});

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

关于javascript - React-native:将场景绑定(bind)到 NavigationBar,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39066452/

相关文章:

javascript - 在 Javascript 中将字符转换为星号

asp.net - jquery ajax 可以调用外部 web 服务吗?

ios - 仅在 ios 设备上 react native "No bundle URL present"

flutter - 如何在 token 或刷新 token 过期时使用 bloc in flutter 将用户重定向到注销页面

javascript - react native 如何实现后退按钮

angular - 类型 'wakeLock' 上不存在属性 'Navigator'

javascript - 使用 JavaScript 转到页面并自动执行该页面上的功能

javascript - 我如何在两个 nuxt 页面之间转换,同时首先等待子组件转换/动画完成?

javascript - 如何将 expo 应用程序连接到 google firestore?

javascript - FCM 消息负载错误,数据对象内的嵌套对象错误