如何在任何不在React Native中的App.js内的js类的屏幕之间导航

时间:2018-03-14 06:42:18

标签: react-native

从App.js类中的一个屏幕导航到另一个屏幕非常容易。我所做的是做了三个类:App.js,SearchList.js和Detail.js。但我面临的问题是如何在searchList.js类中的任何视图上从searchList.js导航到Detail.js。我应该在searchList.js中再次使用StackNavigator还是在App.js中声明所有类?

App.js

import React from 'react';
import { Image,Button, View, Text ,StatusBar,StyleSheet,Platform,TouchableOpacity,ImageBackground,Picker,Alert,TouchableHighlight} from 'react-native';
import { StackNavigator,DrawerNavigator,DrawerItems } from 'react-navigation';
import {Constants} from "expo";
import SearchList from './classes/SearchList';
import Detail from './classes/Detail';

const DrawerContent = (props) => (
  <View>
    <View
      style={{
        backgroundColor: '#f50057',
        height: 160,
        alignItems: 'center',
        justifyContent: 'center',
      }}
    >
      <Text style={{ color: 'white', fontSize: 30 }}>
        Header
      </Text>
    </View>
    <DrawerItems {...props} />
  </View>
)

class HomeScreen extends React.Component {

 static navigationOptions = {
    drawerLabel: 'Home',
    drawerIcon: ({ tintColor }) => (
      <Image
        source={require('./images/crown.png')}
        style={[styles.icon, {tintColor: '#f50057'}]}
      />
    ),
  };

  constructor(){
    super();
    this.state={PickerValueHolder : ''}
  }

  GetSelectedPickerItem=()=>{
    Alert.alert(this.state.PickerValueHolder);
  }

  render() {
    return (

      <ImageBackground  source={require('./images/green.png')} style={styles.backgroundImage} >

       <TouchableOpacity onPress={() =>this.props.navigation.navigate('DrawerOpen')}>
         <Image
          source={require('./images/menu-button.png')} 
          style={styles.imagesStyle}
        />
        </TouchableOpacity>


        <View style={styles.columnContainer}>

          <TouchableHighlight style={styles.search} underlayColor='#fff'  onPress={() => this.props.navigation.navigate('SearchList')}>
            <Text style={styles.searchText}>Search Hotels</Text>
          </TouchableHighlight>
         </View>

        </ImageBackground >

    );
  }
}

class DetailsScreen extends React.Component {
  render() {
    return (
      <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
        <Text>Details Screen</Text>
        <Button
          title="Go to Details... again"
          onPress={() => this.props.navigation.navigate('Details')}
        />
      </View>
    );
  }
}

const styles = StyleSheet.create({

    backgroundImage: {
    flex: 1,
    width: null,
    height: null,
    marginTop: Constants.statusBarHeight,
  },
  search:{
    marginTop:20,
    paddingTop:15,
    borderRadius:8,
    borderColor: '#fff'
  },
  searchText:{
      color:'#fff',
      textAlign:'center',
  }
     //  backgroundColor: '#ef473a', // app color
});

const HomeStack = StackNavigator({
    Home: {
    screen: HomeScreen,
    navigationOptions: ({ navigation }) => ({
    header: null,
    })  
  },
  SearchList: { screen: SearchList },
  Detail: { screen: Detail},
});

const RootStack = DrawerNavigator(
  {
    Home: {
      screen: HomeStack,
    },
    DetailsScreen: {
      screen: DetailsScreen,
    },
  },
  {
    initialRouteName: 'Home',
  }
);

export default class App extends React.Component {
  render() {
    return <RootStack />;
  }
}

SearchList.js

import React, { Component } from 'react';
import { StyleSheet, Platform, View, ActivityIndicator, FlatList, Text, Image, Alert, YellowBox,ImageBackground } from 'react-native';
import { StackNavigator,} from 'react-navigation';
import Detail from './classes/Detail';

export default class SearchList extends Component {

 constructor(props) {
   super(props);
   this.state = {isLoading: true}

   YellowBox.ignoreWarnings([
    'Warning: componentWillMount is deprecated',
    'Warning: componentWillReceiveProps is deprecated',
  ]);

 }

GetItem (flower_name) {

 Alert.alert(flower_name);

 }

 FlatListItemSeparator = () => {
   return (
     <View
       style={{
         height: .0,
         width: "100%",
         backgroundColor: "#000",
       }}
     />
   );
 }  

 webCall=()=>{

  return fetch('https://reactnativecode.000webhostapp.com/FlowersList.php')
         .then((response) => response.json())
         .then((responseJson) => {
           this.setState({
             isLoading: false,
             dataSource: responseJson
           }, function() {
             // In this block you can do something with new state.
           });
         })
         .catch((error) => {
           console.error(error);
         });

 }

 componentDidMount(){

  this.webCall();

 }

 render() {

   if (this.state.isLoading) {
     return (

      <View style={{flex: 1, justifyContent: 'center', alignItems: 'center'}}>

         <ActivityIndicator size="large" />

       </View>

     );

   }

   return (

     <View style={styles.MainContainer}>

       <FlatList

        data={ this.state.dataSource }

       ItemSeparatorComponent = {this.FlatListItemSeparator}

        renderItem={({item}) => 

              <ImageBackground  source= {{ uri: item.flower_image_url }} style={styles.imageView}  
              onPress={() => this.props.navigation.navigate('Detail')}>
                </ImageBackground>

          }

        keyExtractor={(item, index) => index.toString()}

        />

     </View>
   );
 }
}

const styles = StyleSheet.create({

MainContainer :{
    justifyContent: 'center',
    flex:1,
    margin: 5,
    marginTop: Constants.statusBarHeight , //(Platform.OS === 'ios') ? 20 : 14,
},

imageView: {
    width: '100%',
    height: 220 ,
    margin: 7,
    borderRadius : 40,
},

});


const HomeStack = StackNavigator({
 Detail: { screen: Detail},
});

export default class App extends React.Component {
  render() {
    return <HomeStack  />;
  }
}

任何帮助都会很明显。

3 个答案:

答案 0 :(得分:2)

要导航到您需要拥有导航对象的任何屏幕。可以通过两种方式提供导航对象

  1. StackNavigator
  2. 中声明
  3. 明确地将其作为道具传递给其他屏幕
  4. 如果您使用第一种方法,并且需要从SecondScreen导航到ThirdScreen,则应首先在StackNavigator中声明两个屏幕,然后导航才会成功

    如果您使用任何普通组件(例如模态框)导航到另一个屏幕,您需要做的就是将导航道具(this.props.navigation)传递给模态框组件并使用道具导航到另一个屏幕。这里唯一的要求是this.props.navigation应该在加载模态框组件的类中可用。

    修改

    根据要求,这是片段

    const App = StackNavigator({
        FirstScreen: { screen: FirstScreen},
        SecondScreen: { screen: SecondScreen},
        ThirdScreen: { screen: ThirdScreen}
    })
    
    export default App;
    

    SecondScreen中,声明对象const { navigate } = this.props.navigation;并点击一下按钮,使用此对象导航到另一个屏幕navigate("ThirdScreen");

    关于第二种方法,如果您的组件是模态,则可以将navigate对象作为 - <Modal navigation={navigate} />传递,并在模态组件中将其用作this.props.navigation("ThirdScreen");

    希望现在澄清一下。

答案 1 :(得分:0)

支持我们将js命名为SecondScreen.jsApp.js位于同一目录级别,然后我们应该在App.js

中将其导入
import SecondScreen from './SecondScreen';

它对我有用。希望这对你也有帮助。

答案 2 :(得分:0)

我认为您正在尝试实现堆栈导航器的功能。 转到React-Navigation-Docs。在堆栈导航器中,您可以制作一叠屏幕,并从一个屏幕导航到另一个屏幕。在index.js里面:

    import { StackNavigator, TabNavigator } from "react-navigation";
    import SplashScreen from "./src/screens/start/splash";
    import LoginScreen from "./src/screens/start/login";
    import DomainScreen from "./src/screens/start/domain";


        const App = StackNavigator(
          {
            Splash: {
              screen: SplashScreen,
            },
            Domain: {
              screen: DomainScreen,
            },
            Login: {
              screen: LoginScreen,
            },
            Tabs: {
              screen: HomeTabs,
            }
          },
          {
            initialRouteName: "Splash",
          }
        );
AppRegistry.registerComponent("app_name", () => App);

然后您可以使用this.props.navigation.navigate("ScreenName")

导航到这些屏幕中的任何一个