2017-10-10 45 views
0

React-Native初学者在这里。我正在尝试使用带有Typescript的React-Native中的TabNavigation使StackNavigation工作。我的应用中有三个屏幕。 FirstScreenSecondScreen显示为选项卡,在单击FirstScreen中的“单击此处”按钮时显示PopScreenthis.props.navigation.navigate("Pop")调用按钮点击似乎失败没有任何错误,但它返回falsereact-navigation无法显示在StackNavigator中添加的屏幕

这里是我的代码:

import React from "react"; 
import { View, Text, Button } from "react-native"; 
import { StackNavigator } from 'react-navigation'; 
import { TabNavigator, NavigationStackScreenOptions } from 'react-navigation'; 

class FirstScreen extends React.Component<any, any> { 
    render() { 
     return (
      <View> 
       <Text>My First Tab Screen!!!</Text> 
       <Button 
        title="Click Here" 
        onPress={() => this.props.navigation.navigate("Pop"); } /> 
      </View> 
     ); 
    } 
} 

class SecondScreen extends React.Component<any, any> { 
    render() { 
     return (
      <Text>My Second Tab Screen</Text> 
     ); 
    } 
} 

class PopScreen extends React.Component<any, any> { 
    render() { 
     return (
      <View> 
       <Text>Content in pop up.</Text> 
      </View> 
     ); 
    } 
} 

const TabOptions = TabNavigator({ 
    MyFirst: { screen : FirstScreen }, 
    MySecond: { screen : SecondScreen } 
}); 

class TabOptionsScreen extends React.Component<any, any> 
{ 
    static navigationOptions : NavigationStackScreenOptions = { 
     header: null 
    }; 

    render() { 
     return (<TabOptions />) 
    } 
} 

export const App = StackNavigator ({ 
    Home : { screen: TabOptionsScreen }, 
    Pop: { screen: PopScreen } 
}) 

this.props.navigation对象不为空或FirstScreen类不确定的,但不知它不承认在StackNavigator传递的选项。请帮助我如何让navigate方法在TabNavigator的任何一个儿童屏幕上工作?

回答

0

经过几次读取后,我意识到this.props.navigator是使用它的Navigator专用的。 TabNavigator中的navigator可用于在选项卡之间切换,并且StackNavigator中的navigator可将屏幕推入或从屏幕堆栈弹出。导航器中的屏幕会继承父对象的navigator对象,但它们不会深入屏幕层次结构中。所以有两种解决方案:

第一个解决方案几乎与Guilherme建议的解决方案相同,但是在TabNavigator中我不是通过navigationOptions,而是在StackNavigator中将其传递给关联的屏幕。

const TabOptions = TabNavigator({ 
    MyFirst: { screen : FirstScreen }, 
    MySecond: { screen : SecondScreen } 
}); 
// TabOptionsScreen class removed here. 
// TabOptions constant is directly passed in StackNavigator. 
export const App = StackNavigator ({ 
    Home : { 
     screen: TabOptions, 
     navigationOptions : { 
      header: null 
     } 
    }, 
    Pop: { screen: PopScreen } 
}) 

现在我可以在FirstScreen组件中使用this.props.navigation.navigate("Pop")。它还使我们能够导航到同一级别的其他选项卡 - this.props.navigation.navigate("MySecond")

在我的原始代码中,我将所有屏幕写入单独的文件中,并且我希望屏幕的navigationOptions在它自己的类定义中。所以第二个解决方案就是这种模块化方法

export class FirstScreen extends React.Component<any, any> { 
    render() { 
     const { navigate } = this.props.screenProps.navigation; 
     return (
      <View> 
       <Text>My First Tab Screen!!!</Text> 
       <Button 
        title="Click Here !!!" 
        onPress={() => navigate("Pop") }/> 
      </View> 
     ); 
    } 
} 

const TabOptions = TabNavigator({ 
    MyFirst: { screen : FirstScreen }, 
    MySecond: { screen : SecondScreen } 
}); 

export class TabOptionsScreen extends React.Component<any, any> 
{ 
    static navigationOptions : NavigationStackScreenOptions = { 
     header: null, 
    }; 

    render() { 
     return (<TabOptions screenProps={{ navigation: this.props.navigation }} />) 
    } 
} 

export const App = StackNavigator ({ 
    Home : { screen: TabOptionsScreen }, 
    Pop: { screen: PopScreen } 
}) 

在这段代码,TabOptionsScreenStackNavigator直接孩子,所以navigation对象也被传递到它,但现在我们必须手动传递navigation对象TabOptions导航。 screenProps可用于从父组件传递道具给儿童。在FirstScreen中,使用this.props.screenProps.navigation进行堆栈导航,使用this.props.navigation进行标签导航。