我试图在用户点击其中一个列表项时显示详细信息视图。当用户点击listitem时,我收到错误消息,指出Undefined不是对象 评估' this.props.services.ser。以下是错误的屏幕截图:
我的列表项页面代码如下:
import React, { Component } from 'react';
import { Text, View, StyleSheet, ListView } from 'react-native';
import { Provider, connect } from 'react-redux';
import { createStore } from 'redux'
import reducers from '../reducers/ServiceReducer';
import ServiceItem from './ServiceItem';
import Icon from 'react-native-vector-icons/EvilIcons';
import ServiceDetail from './ServiceDetail';
const styles = StyleSheet.create({
container: {
flex: 1,
width: 353,
flexWrap: 'wrap',
paddingTop: 20,
paddingLeft: 20,
},
});
const store = createStore(reducers);
class AutoCompActivity extends Component {
renderInitialView() {
const ds = new ListView.DataSource({
rowHasChanged: (r1, r2) => r1 !== r2,
});
this.dataSource = ds.cloneWithRows(this.props.services);
if (this.props.detailView === true) {
return (
<ServiceDetail />
);
} else {
return (
<ListView
enableEmptySections={true}
dataSource={this.dataSource}
renderRow={(rowData) =>
<ServiceItem services={rowData} />
}
/>
);
}
}
render() {
return (
<View style={styles.container}>
{this.renderInitialView()}
</View>
);
}
}
const mapStateToProps = state => {
return {
services: state.services,
detailView: state.detailView,
};
};
const ConnectedAutoCompActivity = connect(mapStateToProps)(AutoCompActivity);
const app1 = () => (
<Provider store={store}>
<ConnectedAutoCompActivity />
</Provider>
)
export default app1;
我向用户显示的每个项目都在js类serviceItem.js中定义。下面是serviceItem.js的代码。我把整个代码放在TouchableWithoutFeedback中。这是当用户点击其中一个listItem时出现错误的时候。我多次看了这段代码,但无法弄清楚我做错了什么
import React from 'react';
import { Text, View, StyleSheet, Image, TouchableWithoutFeedback } from 'react-native';
import { connect } from 'react-redux';
import { getTheme } from 'react-native-material-kit';
import Icon from 'react-native-vector-icons/EvilIcons';
import * as actions from '../actions';
const theme = getTheme();
const styles = StyleSheet.create({
card: {
marginTop: 20,
},
title: {
top: 20,
left: 80,
fontSize: 24,
},
image: {
height: 100,
},
action: {
backgroundColor: 'black',
color: 'white',
},
icon: {
position: 'absolute',
top: 15,
left: 0,
color: 'white',
backgroundColor: 'rgba(255,255,255,0)',
},
});
const ServiceItem = (props) => {
return (
<TouchableWithoutFeedback
onPress={() => props.selectServices(props.services)}
>
<View style={[theme.cardStyle, styles.card]}>
<Text >{props.services.ser} </Text>
</View>
</TouchableWithoutFeedback>
);
};
const mapStateToProps = state => {
return {
selectServices: state.selectServices,
services: state.services
};
};
export default connect(mapStateToProps, actions)(ServiceItem);
当用户点击每个列表项时。我正在调用ServiceDetail.js类。下面是serviceDetail.js类的代码:
/**
* Sample React Native App
* https://github.com/facebook/react-native
* @flow
*/
import React, { Component } from 'react';
import { Text, View, StyleSheet, Image, ScrollView, TouchableOpacity, Linking } from 'react-native';
import { connect } from 'react-redux';
import { getTheme } from 'react-native-material-kit';
import EvilIcon from 'react-native-vector-icons/EvilIcons';
import MaterialIcon from 'react-native-vector-icons/MaterialIcons';
import SimpleIcon from 'react-native-vector-icons/SimpleLineIcons';
import * as actions from '../actions';
const theme = getTheme();
const styles = StyleSheet.create({
card: {
marginTop: 10,
paddingBottom: 20,
marginBottom: 20,
borderColor: 'lightgrey',
borderWidth: 0.5,
},
title1: {
top: 10,
left: 80,
fontSize: 24,
},
title2: {
top: 35,
left: 82,
fontSize: 18,
},
image: {
flex: 0,
height: 100,
width: 333,
backgroundColor: 'transparent',
justifyContent: 'center',
alignItems: 'center',
},
closeIcon: {
position: 'absolute',
top: 5,
left: 295,
color: 'rgba(233,166,154,0.8)',
backgroundColor: 'rgba(255,255,255,0)',
},
icon: {
position: 'absolute',
top: 15,
left: 0,
color: 'white',
backgroundColor: 'rgba(255,255,255,0)',
},
textArea: {
flexDirection: 'row',
paddingLeft: 20,
paddingTop: 10,
width: 260,
},
textIcons: {
color: '#26a69a',
},
actionArea: {
paddingTop: 10,
flexDirection: 'row',
justifyContent: 'space-around',
alignItems: 'center',
},
});
class ServiceDetail extends Component {
handleClick = (link) => {
Linking.canOpenURL(link).then(suppported => {
if (supported) {
Linking.openURL(link);
} else {
console.log('Don\'t know how to open URI: ' + link);
}
});
};
render() {
return (
<ScrollView showsVerticalScrollIndicator={false}>
<View style={[theme.cardStyle, styles.card]}>
<Image
source={require('../images/background.jpg')}
style={[theme.cardImageStyle, styles.image]}
/>
<EvilIcon name={'user'} size={100} style={styles.icon}/>
<SimpleIcon name={'close'} size={30} style={styles.closeIcon}
onPress={() => this.props.noneSelected()} />
<Text style={[theme.cardTitleStyle, styles.title1]}>{this.props.services.ser}</Text>
<Text style={[theme.cardTitleStyle, styles.title2]}>from {this.props.services.Location}</Text>
<Text style={[theme.cardTitleStyle, styles.title2]}>from {this.props.services.SecondLoc}</Text>
<View style={styles.textArea}>
<MaterialIcon name={'phone'} size={40} style={styles.textIcons}/>
<Text style={theme.cardContentStyle}>{this.props.services.Phone}</Text>
</View>
<View style={styles.textArea}>
<MaterialIcon name={'email'} size={40} style={styles.textIcons}/>
<Text style={theme.cardContentStyle}>{this.props.services.email}</Text>
</View>
<View style={styles.actionArea}>
<Text>Call</Text>
<Text>Email</Text>
</View>
</View>
</ScrollView>
);
}
}
const mapStateToProps = state => {
return {
service: state.serviceSelected,
};
};
export default connect(mapStateToProps, actions)(ServiceDetail);
我的index.js类在actions文件夹下有以下代码:
export const selectServices = (serviceId) => {
return {
type: 'SELECTED_SERVICE',
payload: serviceId,
};
};
export const noneSelected = () => {
return {
type: 'NONE_SELECTED',
};
};
我的serviceReducer具有以下代码:
import services from './services.json';
const initialState = {
services,
detailView: false,
serviceSelected: null,
};
export default (state = initialState, action) => {
switch (action.type) {
case 'SELECTED_SERVICE':
return {
...state,
detailView: true,
serviceSelected: action.payload
}
case 'NONE_SELECTED':
return {
...state,
detailView: false,
serviceSelected: null,
}
default:
return state;
}
}
我正在Android模拟器上的Windows机器上开发这个应用程序。我知道我错过了什么。我查看了每一行,但无法弄清楚我做错了什么。我是新来回应原生并试图按照这个例子来制作这个应用程序。我尝试使用chrome调试应用程序,但不断收到无法连接到远程调试的错误。
任何帮助都将受到高度赞赏。
答案 0 :(得分:0)
我看到你传递道具并将其用于const ServiceItem
。您需要使用mapStateToProps
,然后转到connect
serviceItem.js
。
const mapStateToProps = state => {
return {
selectServices: state.selectServices,
services: state.services
};
};
export default connect(mapStateToProps, actions)(ServiceItem);
您的ServiceDetail.js也应该是:
const mapStateToProps = state => {
return {
services: state.services
};
};
export default connect(mapStateToProps, actions)(ServiceDetail);
答案 1 :(得分:0)
您的ServiceItem组件只是一个表示组件,在我看来,它不需要连接到redux存储,而是将数据和事件挂钩从父传递到ServiceItem组件,这将工作得很好。这也将解决您的道具问题。
“DennisFrea”提出的观点仍然很好。我只是建议另一个达到同样的目的。