【问题标题】:How to pass the navigator object to the components used in the react natives root file?如何将 navigator 对象传递给 react native 根文件中使用的组件?
【发布时间】:2016-09-28 15:16:26
【问题描述】:

下面是我的应用组件:

/**
 * Class app from where the app bootstraps
 */
export default class App extends Component {
  constructor(props) {
    super(props);
  }

  // This is where all your routes will be processed
  renderScene(route, navigator) {
    // Set a variable to get the route
    let RouteComponent = route.component;

    _navigator = navigator;

    // With props return the components
    return (
      <RouteComponent navigator={navigator} {...route.passProps} />
    );
  }

  static navigationBarRouteMapper = openControlPanel => ({
      LeftButton: function(route, navigator, index, navState) {
        return (

          // Hamburger icon which on clicked opens the menu
          <TouchableOpacity style={navBarStyle.left} onPress={() => openControlPanel()}>
            <View>
              {hamburgerIcon}
            </View>
          </TouchableOpacity>
        );
      },
      RightButton: function(route, navigator, index, navState) {
        return (
          // cart menu
          <TouchableWithoutFeedback onPress={() => dismissKeyboard()}>
            <View style={navBarStyle.right}>
              {cartIcon}
              <View style={navBarStyle.counter}>
                <Text style={navBarStyle.counterText}>20</Text>
              </View>
            </View>
          </TouchableWithoutFeedback>
        );
      },
      Title: function(route, navigator, index, navState) {
        // Title of the route
        return (
          <TouchableWithoutFeedback onPress={() => dismissKeyboard()}>
            <View style={navBarStyle.titleWrap}>
              <Text style={navBarStyle.title}>{route.title.toUpperCase()}</Text>
            </View>
          </TouchableWithoutFeedback>
        );
      }
  })

  // Close the menu drawer
  closeControlPanel() {
    this._drawer.close();
  }

  // open the menu drawer
  openControlPanel() {
    this._drawer.open();
    dismissKeyboard();
  }

  // On clicking the menu item, this function routes to that menu item page
  getNavigator(route) {
    this.refs.navigator.replace(route);
    this.closeControlPanel();
  }

  render() {

    return (
      <Drawer
        ref={ (ref) => { this._drawer = ref; } }
        type="overlay"
        content={<Menu navigator={this.getNavigator.bind(this)} menuItems={menu} closeControlPanel={this.closeControlPanel.bind(this)} />}
        onOpenStart={() => dismissKeyboard()}
        tapToClose={true}
        openDrawerOffset={0.2}
        panCloseMask={0.2}
        panOpenMask={20}
        acceptPan={true}
        closedDrawerOffset={-3}
        styles={drawerStyle}
        tweenHandler={(ratio) => ({

          // This code will maintain the opacity for main
          // Whilst the opacity for the mainOverlay on the screen will be faded.
          main: { opacity: 1 },
          mainOverlay: {
            opacity: ratio / 2,
            backgroundColor: 'black',
          }

        })}>

        <Navigator
          initialRoute={homeScene}
          renderScene={this.renderScene}
          ref="navigator"
          // Navbar of the app
          navigationBar={
            <Navigator.NavigationBar
              routeMapper={App.navigationBarRouteMapper(this.openControlPanel.bind(this))}
              style={navBarStyle.navBar}
            />
          }
        />

        <EditSearch />
      </Drawer>
    );
  }
}

在最底部,您会看到 &lt;EditSearch&gt; 组件,其中包含两个文本输入。该组件对应用程序中除主页外的所有页面都是通用的。

因此,我想知道我当前在哪个页面或场景上,以便我可以检查该场景/页面是否是主页。如果它是主页,我会隐藏该组件,否则我会在所有其他页面上显示它。

我尝试像这样通过 ref 传递导航器:

<EditSearch nav={this.refs.navigator} />

但是,我在 &lt;EditSearch&gt; 组件上未定义,并且当页面更改时视图不会重新呈现,因为它没有检测到任何状态更改。

我可以这样做:

this.state = {
  currentRoute: 'home'
}

然后在路由改变的时候改变这个状态。但是,我无法更改 renderScene 中的状态,因为在 renderScene 中设置状态会导致无限循环。如果我可以在路由更改时使用页面标题设置此状态,那么我可以将该状态发送到&lt;EditSearch&gt; 组件。

我很困惑如何将当前路由信息传递给这个公共组件。感谢期待。

【问题讨论】:

    标签: reactjs react-native react-native-android


    【解决方案1】:

    好的,我找到了解决方案,但我不确定它是否合适。

    所以下面是我的解决方案。

    首先我创建了状态和函数来设置该状态:

      constructor(props) {
        super(props);
    
        this.state = {
          isHome: false
        };
    
        this.setIsHome = this.setIsHome.bind(this);
      }
    
      setIsHome(flag) {
        // Set state to let component know whether the page is home or not
        this.setState({
          isHome: flag ? flag : false
        });
      }
    

    然后将函数传递给所有页面,这些页面可以隐藏或显示&lt;EditSearch&gt;组件:

    <RouteComponent navigator={navigator} {...route.passProps} setIsHome={this.setIsHome} />
    

    然后我将isHome 状态传递给&lt;EditSearch&gt; 组件:

    <EditSearch isHome={ this.state.isHome } />
    

    这就是我在 home 组件中调用函数的方式:

      componentWillMount() {
        this.props.setIsHome(true);
      }
    
      componentWillUnmount() {
        this.props.setIsHome(false);
      }
    

    这就是我显示/隐藏组件的方式。我希望它会有所帮助。但是,如果知道如何将 navigator 对象传递给此类组件,那就太好了。

    【讨论】:

      【解决方案2】:

      这是 Drawer Github 问题的解决方案。

      找到了一个快速的解决方法,但这并不理想。如果你把 带有抽屉组件的导航器,然后在 Navigator.NavigationBar 你可以设置 this.navigator = this.navigator || 导航器,然后您可以将导航器传递给您的内容 抽屉的组件。

      <Drawer
        content={<Main navigator={this.navigator}/>}
        type='overlay'>
      
        <Navigator
          renderScene={renderScene}
          navigationBar={
      
            <Navigator.NavigationBar
              routeMapper={{
                LeftButton: (route, navigator, index, navState) => {
      
                  this.navigator = this.navigator || navigator;
      
                  return (
                    <View>
                      <Text>Something</Text>
                    </View>
                  );
                }
              }}
            />
        />
      </Drawer>
      

      https://github.com/root-two/react-native-drawer/issues/187#issuecomment-231461585

      【讨论】:

        猜你喜欢
        • 2019-01-18
        • 1970-01-01
        • 2018-01-15
        • 2021-03-08
        • 2019-05-15
        • 2019-02-18
        • 2016-09-15
        • 1970-01-01
        • 2018-12-28
        相关资源
        最近更新 更多