2016-09-27 47 views
0

下面是我的应用程序组件:如何将导航器对象传递给反应原生根文件中使用的组件?

/** 
* 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> 
    ); 
    } 
} 

在最底层,你会看到<EditSearch>组件包含两个文本输入。除了主页之外,该组件对于应用中的所有页面都是通用的。

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

我试图通过裁判通过导航像这样:

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

但是,我得到的<EditSearch>组件上未定义和视图不重新渲染时,页面的变化,因为它没有检测到任何状态变化。

我可以这样做:

this.state = { 
    currentRoute: 'home' 
} 

然后改变这种状态路由变化时。但是,我无法在renderScene中更改状态,因为renderScene中的设置状态会导致无限循环。如果我可以在路由更改时将页面标题设置为此状态,则可以将该状态发送到<EditSearch>组件。

我很困惑如何将当前路线信息传递给这个通用组件。感谢预期。

回答

0

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

下面是我的解决方案。

首先,我创建的状态和功能设置状态:

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

然后函数传递给所有的网页,这些网页可以隐藏或显示<EditSearch>组件:

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

然后我通过isHome状态到<EditSearch>组件:

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

这是我如何调用在家里组件的功能:

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

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

我这是怎么显示/隐藏组件。我希望这有帮助。但是,知道如何将导航器对象传递给这些组件真的很不错。

0

下面是抽屉Github问题的解决方案。

找到了一个快速的解决方法,但它并不理想。如果您将 Navigator与Drawer组件包装起来,那么在 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

相关问题