undefined不是一个对象(评估' _this2.props.navigation)

时间:2017-06-08 11:00:37

标签: android listview react-native navigation-drawer

我是新手,反应原生并试图自己学习。我已经实现了导航抽屉并制作了一些屏幕。在我的演示中,我有listview,我只是试图将用户导航到选定的项目详细信息页面,但我得到上述错误。

这是index.android.js文件: -

import React, { Component } from 'react';
import {
  AppRegistry,
} from 'react-native';
import Main from './src/Main'
import { DrawerNavigator } from 'react-navigation';
import { TabNavigator } from 'react-navigation';
import LoginScreen from './src/LoginScreen';
import { StackNavigator } from 'react-navigation';
import movielisting from './src/movielisting';
class reactNavigationSample extends Component {
  render(){
    const { navigation } = this.props;
    return (
  <MyComponent navigation={navigation}/>
    );
  }
}
const DrawerApp = DrawerNavigator({
    movielisting: {screen: movielisting},
      LoginScreen:{ screen: Main},

});
AppRegistry.registerComponent('reactNavigationSample', () => DrawerApp);

列表页: -

import React, { Component } from 'react';
import { StatusBar } from 'react-native'
import { StackNavigator } from 'react-navigation';
import { NavigationActions } from 'react-navigation';
import { Actions, ActionConst } from 'react-native-router-flux';

import home  from './images/home.png';
import ActionBar from './ActionBar';
import ProgressBar from './ProgressBar';
const { width: viewportWidth, height: viewportHeight } = Dimensions.get('window');
import {
  StyleSheet,
  Text,
  Image,
  View,
  AsyncStorage,
  TouchableOpacity,TouchableHighlight,Dimensions,ListView
} from 'react-native';
const uri = 'http://csswrap.com/wp-content/uploads/2015/03/showmenu.png';


export default class movielisting extends Component {

 constructor(props) {
     super(props);
     var ds = new ListView.DataSource({rowHasChanged: (r1, r2) => r1 !== r2});
     this.state = {
       moviesData: ds.cloneWithRows([]),
     };
   }
   componentDidMount() {
       this.fetchMoviesData();
     }
    renderRow(rowData){
    AsyncStorage.setItem('moviesData', JSON.stringify(rowData));
        return (
          <View style={styles.thumb} >
          <TouchableOpacity onPress={() => this.props.navigation.navigate('MovieDeatilScreen')}>
            <Image
              source={{uri:'https://image.tmdb.org/t/p/w500_and_h281_bestv2/'+rowData.poster_path}}
              resizeMode="cover"
              style={styles.img} />
              <Text style={styles.txt}>{rowData.title} (Rating: {Math.round( rowData.vote_average * 10 ) / 10})</Text>
          </TouchableOpacity>
          </View>

        );
      }
      fetchMoviesData() {
          var url = 'http://api.themoviedb.org/3/movie/now_playing?api_key=17e62b78e65bd6b35f038505c1eec409';
          fetch(url)
            .then( response => response.json() )
            .then( jsonData => {
              this.setState({
                moviesData: this.state.moviesData.cloneWithRows(jsonData.results),
              });
            })
          .catch( error => console.log('Error fetching: ' + error) );
        }
  render() {
        return (
                <View style={styles.container}>
                <View style={styles.navBar}>
                 <TouchableOpacity onPress={() => this.props.navigation.navigate('DrawerOpen')} style={styles.action} >
                                                             <Image style={styles.avatar} source={{uri}} />
                                                                  </TouchableOpacity>

                          <Text style={styles.navBarHeader}>Movie List Screen</Text>
                        </View>
                    <ListView
                            dataSource={this.state.moviesData}
                            renderRow={this.renderRow}
                            enableEmptySections={true}
                             style={styles.ListViewcontainer}
                          />
                 <View style={styles.footer}>
                               <ActionBar />
                                </View>
                    </View>
        );
    }
    renderLoader(){
            return (
                this.state.showLoader?<View><Spinner color='red' /></View>:null
            )
        }
    hideLoader(){
            setTimeout(() => {
                this.setState({showLoader:false})
            }, 1);
        }
}
const styles = StyleSheet.create({
  container: {
  position:'relative',
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
    backgroundColor: '#F5FCFF',
  },
  welcome: {
    fontSize: 20,
    textAlign: 'center',
    margin: 10,
  },
          footer: {
            position: 'absolute',
            flex:0.1,
            left: 0,
            right: 0,
            bottom: -12,
            flexDirection:'row',
            height:70,
            alignItems:'center',
          },
                navBar: {
                 position: 'absolute',
                 flexDirection: 'row',
                 top:0,
                 right:0,
                 left:0,
                   paddingTop:15,
                    height: 64,
                    backgroundColor: '#1EAAF1'
                  },
                      navBarHeader: {
                      flex: 1,
                      left:30,
                       paddingTop:5,
                      top:2,
                        color: '#FFFFFF',
                        fontWeight: 'bold',
                        textAlign: 'left',
                      },avatar: {
                      left:10,
                                bottom:3,
                               width: 35,
                               height: 35,
                              },action: {
                                        flex: 0.4,
                                    },thumb: {
                                          backgroundColor: '#ffffff',
                                          marginBottom: 5,
                                          elevation: 1
                                        },
                                        img: {
                                          height: 300
                                        },
                                        txt: {
                                          margin: 10,
                                          fontSize: 16,
                                          textAlign: 'left'
                                        },ListViewcontainer:{
                                         marginTop:110,
                                          bottom: 50,
                                        }
});
 movielisting.navigationOptions = {
  drawer: {
      icon: () => (
        <Image
          source={home}
          style={[styles.tabIcon, {tintColor: 'black'}]}
        />
  )}

};

MovieDetail屏幕页: -

import React, { Component, PropTypes } from 'react';

import {
  AppRegistry,
  StyleSheet,
  Text,
  View,
  Image,
  TouchableOpacity,
  TextInput,
  AsyncStorage,
  Icon
} from 'react-native';
import ActionBar from './ActionBar';
import { StackNavigator } from 'react-navigation';
import { NavigationActions } from 'react-navigation';
import Dimensions from 'Dimensions';
import { Actions, ActionConst } from 'react-native-router-flux';
const uri = 'http://csswrap.com/wp-content/uploads/2015/03/showmenu.png';
export default class MovieDeatilScreen extends Component {

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

componentDidMount() {
        AsyncStorage.getItem("moviesData").then((value) => {
            this.setState({"moviesData": JSON.parse(value)});
//            this.Loaddata();
        }).done();

    }


//   Loaddata() {
//  for(let i = 0; i < this.state.moviesData.length; i++){
//
//  this.setState({'username' : this.state.SignedUpuser[i].name});
//
//    }
//    }

render() {
    return (
    <View style={styles.container}>
    <View style={styles.navBar}>
                     <TouchableOpacity onPress={() => this.props.navigation.navigate('DrawerOpen')} style={styles.action} >
                                                                 <Image style={styles.avatar} source={{uri}} />
                                                                      </TouchableOpacity>

                              <Text style={styles.navBarHeader}>Movie Deatil Screen</Text>
                            </View>
 <View style={styles.thumb}>
            <Image
              source={{uri:'https://image.tmdb.org/t/p/w500_and_h281_bestv2/'+this.state.moviesData.poster_path}}
              resizeMode="cover"
              style={styles.img} />
              <Text style={styles.txt}>{this.state.moviesData.title} (Rating: {Math.round( this.state.moviesData.vote_average * 10 ) / 10})</Text>
          </View>
          <View style={styles.footer}>
                                         <ActionBar />
                                          </View>
          </View>
    );
}
}
const DEVICE_WIDTH = Dimensions.get('window').width;
const DEVICE_HEIGHT = Dimensions.get('window').height;
const styles = StyleSheet.create({
container: {
  position:'relative',
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
    backgroundColor: '#F5FCFF',
  },
  welcome: {
    fontSize: 20,
    textAlign: 'center',
    margin: 10,
  },
          footer: {
            position: 'absolute',
            flex:0.1,
            left: 0,
            right: 0,
            bottom: -12,
            flexDirection:'row',
            height:70,
            alignItems:'center',
          },
                navBar: {
                 position: 'absolute',
                 flexDirection: 'row',
                 top:0,
                 right:0,
                 left:0,
                   paddingTop:15,
                    height: 64,
                    backgroundColor: '#1EAAF1'
                  },
                      navBarHeader: {
                      flex: 1,
                      left:30,
                       paddingTop:5,
                      top:2,
                        color: '#FFFFFF',
                        fontWeight: 'bold',
                        textAlign: 'left',
                      },avatar: {
                      left:10,
                                bottom:3,
                               width: 35,
                               height: 35,
                              },action: {
                                        flex: 0.4,
                                    },thumb: {
                                          backgroundColor: '#ffffff',
                                          marginBottom: 5,
                                          elevation: 1
                                        },
                                        img: {
                                          height: 300
                                        },
                                        txt: {
                                          margin: 10,
                                          fontSize: 16,
                                          textAlign: 'left'
                                        },ListViewcontainer:{
                                         marginTop:110,
                                          bottom: 50,
                                        }
});
MovieDeatilScreen.navigationOptions = {
  drawer: {
      icon: () => (
        <Image
          source={home}
          style={[styles.tabIcon, {tintColor: 'black'}]}
        />
  )}

};

任何人都可以帮我如何导航到列表项单击的详细信息屏幕。我是否需要单独为此功能实现导航器,并且应该使用this.props.navigation.push(tilename和组件名称)?

感谢!!!

1 个答案:

答案 0 :(得分:2)

我想我有一些想法,你得到的问题与功能绑定有关。

renderRow函数无法访问this,这意味着您必须绑定它,您可以在构造函数中执行此操作,或者只是将其设置为箭头函数。

方法1:在构造函数中绑定它,如下所示:

this.renderRow = this.renderRow.bind(this)

方法2:声明中的隐式绑定:

renderRow = (rowData) => { ... }

希望这会奏效。