Navigate when clicking on image doesn't work

2019-08-24 01:47发布

问题:

I've been trying to be able to change screens by clicking on the Image within the code but it isn't working.

I've tried defining Push, navigate and other props but it always says that undefined is not an object and show the prop.

import React from 'react';
import { AppRegistry, StyleSheet, View, Image, TouchableOpacity, Button } from "react-native";
import { widthPercentageToDP as wp, heightPercentageToDP as hp } from 'react-native-responsive-screen'
import { StackNavigator, createStackNavigator, createAppContainer } from 'react-navigation';
import Screen from './Screen'

export default class Additional extends React.Component {
  render(){
    const { navigate } = this.props.navigation;
    return (
      <View style={styles.container}>
        <TouchableOpacity onPress={() =>
          navigate("Screen")}
        >
          <Image
            style={{
              tintColor: "#9B9B9B", height: 56, width: 56,
              position: 'absolute', alignSelf: 'center', top: wp('-84.0%'), left: wp('5%'),
            }}
            source={require("../Icons/XButton.png")}
          />
        </TouchableOpacity>
      </View>
    )
  }
}

const AppNavigator = createStackNavigator({
  Home: {screen: Home},
  Screen: {screen: Screen},
}, {
  initialRouteName: 'Home',
});

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
  }
})

回答1:

Parent:

i

mport React from 'react';
import {AppRegistry, StyleSheet, View, Image, TouchableHighlight} from "react-native" ;
import {widthPercentageToDP as wp, heightPercentageToDP as hp} from 'react-native-responsive-screen'
import Additional from './Additional'
import { createAppContainer, createStackNavigator, StackActions, NavigationActions } from 'react-navigation'; // Version can be specified in package.json
import Screen from './Screen'

export default class SideBar extends React.Component {
    render() {
        return(

        <View style={styles.container}>



        <Additional navigation={this.props.navigation} />


                 </View>
        ) 
    }
}


const AppNavigator = createStackNavigator({
Home: {
    screen: Map,
  },
  Screen: {
    screen: Screen,
  },
}, {

});


const styles= StyleSheet.create({
    container:{ 
         flex: 1,
        backgroundColor: 'rgba(255, 255, 255, 0.81)',
       left: wp('75%'),
        width: 100,


}})

Grandparent:

import React, {Component} from 'react';
import {AppRegistry, Platform, StyleSheet, Text, View, Dimensions} from 'react-native';
import MapView, {Marker} from 'react-native-maps';
import MenuButton from './MenuButton'
import SideBar from './SideBar'





const {width, height} = Dimensions.get ('window')

const SCREEN_HEIGHT = height
const SCREEN_WIDTH = width
const ASPECT_RATIO = height / width
const LATITUDE_DELTA = 0.0922
const LONGITUDE_DELTA = LATITUDE_DELTA * ASPECT_RATIO
export default class App extends Component {

constructor (props) {
super(props)
this.state ={
  initialPosition: {
latitude: 0,
longitude: 0,
latitudeDelta: 0,
longitudeDelta: 0

  },
  markerPosition: {
    latitude: 0,
    longitude: 0
  }
}
  }

watchID: ?number = null

componentDidMount(){

  navigator.geolocation.getCurrentPosition ((position) =>{
var lat = parseFloat(position.coords.latitude)
var long = parseFloat(position.coords.longitude)

var initialRegion = {

latitude : lat,
longitude: long,
latitudeDelta : LATITUDE_DELTA,
longitudeDelta : LONGITUDE_DELTA

}
this.setState({initialPosition: initialRegion})
this.setState({markerPosition: initialRegion})
  },
 (error) => alert (JSON.stringify(error)),
 {enableHighAccuracy: true, timeout: 20000, maximumAge: 1000})

 this.watchID = navigator.geolocation.watchPosition((position) => {
var lat = parseFloat(position.coords.latitude)
var long = parseFloat(position.coords.longitude)

var lastRegion = {
  latitude: lat,
longitude: long,
latitudeDelta : LATITUDE_DELTA,
longitudeDelta : LONGITUDE_DELTA
}
this.setState({initialPosition: lastRegion})
this.setState({markerPosition: lastRegion})

}

 )}


componentWillUnmount(){
   navigator.geolocation.clearWatch(this.watchID)
 }



render() {
    return (
        <View style = {styles.container}>

      <MapView
       customMapStyle={mapStyle}
        style={styles.map}
        region={this.state.initialPosition}>


      <MapView.Marker
     coordinate= {this.state.markerPosition}>
     <View style = {styles.radius}>
       <View style = {styles.marker}>

       </View>
        </View>
     </MapView.Marker>
      </ MapView>
      <SideBar navigation= {this.props.navigation}/>
      <View style={styles.Mstyle}>
<MenuButton navigation= {this.props.navigation}/>
      </View>


</View>
    )

  }
}


const styles = StyleSheet.create({

 radius: {
height: 50,
width: 50,
borderRadius: 50/2,
overflow: 'hidden',
backgroundColor: 'rgba(0, 122, 255, 0.1)',
borderWidth: 1,
borderColor: 'rgba(0, 122, 255, 0.3)',
alignItems: 'center',
justifyContent: 'center'
  },
marker: {

 height: 20,
 width: 20,
 borderWidth: 3,
 borderColor: 'white',
 borderRadius: 20 / 2,
overflow: 'hidden',
backgroundColor: '#007AFF'
},


 Mstyle: {
      alignSelf:'center',
      position: 'absolute'
},

 container: {
  flex: 1,
  justifyContent: 'center',

  backgroundColor: '#F5FCFF'

 },
 map: {
  left: 0,
  right: 0,
  top: 0,
  bottom: 0,
  position: 'absolute'
 },

});


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


回答2:

Because Additional is not in createStackNavigator screens list. So, this.props.navigation is undefined. To cover this, first, you have to export default AppNavigator , and in another component (for example Additional) you must use withNavigation method.

In root component:

export default createStackNavigator({
  Home: {screen: Home},
  Screen: {screen: Screen},
}, {
  initialRouteName: 'Home',
});

In Additional component:

import {withNavigation} from 'react-navigation'

class Additional extends React.Component {
  // ...
}

export default withNavigation(Additional)