React Native - 模态不渲染
React Native - Modal not rendering
这是 render
函数,它应该不包括 RespondToInquiry
组件:
HomeScreen.js
componentDidMount() {
console.log('key for stack navigator:',this.props.navigation.dangerouslyGetParent().state.key);
this._sub = this.props.navigation.addListener(
'didFocus',
() => {
console.log('in didFocus for HomeScreen');
if(this.props.navigation.getParam('data', '') != '') {
console.log('showRespondTo fired.');
this.setState({info: this.props.navigation.getParam('data', '')})
this.setState({showRespondTo: true});
}
}
);
....
}
render() {
console.log('in render of HomeScreen',this.props.navigation.getParam('data', ''),this.state.showRespondTo);
return (
<View style={{flex:1}}>
{this.state.showRespondTo && this.returnRespond()}
<TouchableWithoutFeedback onPress={Keyboard.dismiss}>
<View style={styles.container}>
<MultiSelectList
style={{backgroundColor: '#ffe4c4'}}
data={this.state.items}
renderItem={this.renderListItems}
numColumns={2}
contentContainerStyle={{}}
onEndReachedThreshold={0.5}
maxToRenderPerBatch={2}
initialNumToRender={4}
ListHeaderComponent={this.renderHeader}
getItemLayout={(data, index) => (
{length: Dimensions.get('window').height/2, offset: Dimensions.get('window').height/2 * index, index}
)}
backgroundColor={this.state.backgroundColor}
/>
</View>
</TouchableWithoutFeedback>
</View>
);
}
console.log('in render of HomeScreen',this.props.navigation.getParam('data', ''),this.state.showRespondTo);
的输出是:
in render of HomeScreen (2)
{tempId: "1537747945332", message: "Hi, I would like to rent an item from you.", dates: "[]"}
true
所以你可以看到 this.state.showRespondTo
是真的,所以它应该呈现 RespondToInquiry
,但它没有。
这就是 RespondToInquiry.js
的样子:
_renderModalContent = () => (
<TouchableWithoutFeedback onPress={() => {if(this.state.keyboardOpen) {Keyboard.dismiss()}}}>
<Animated.View
style={{
paddingTop: 5,
paddingBottom: 10,
paddingLeft: 10,
paddingRight: 10,
marginTop: this.state.yPosition,
marginBottom: this.state.yPositionPositive,
flex: 1,
marginLeft: (Dimensions.get('window').width - 300) / 4,
backgroundColor: 'rgba(0,0,0,0.8)',
width: 300,
borderRadius: 4,
borderWidth: 0,
}}>
<View style={{ flexDirection: 'column', justifyContent: 'space-between', flex: 1 }}>
<View style={{flexDirection: 'column', justifyContent: 'space-between', flex: 0, backgroundColor: '#e6fffe', marginTop: 5}}>
<View style={{flex: 0, backgroundColor: '#e6fffe', flexDirection: 'row', justifyContent: 'center', alignItems: 'center', paddingBottom: 10, borderBottomColor: '#6de3dc', borderBottomWidth: 0}}>
<View style={{justifyContent: 'center', alignItems: 'center', flex: 0.5}}>
<View style={{flexDirection: 'column', justifyContent: 'space-between'}}>
<Image
source={require('../assets/billythekid2.jpg')}
style={{height: 60, width: 60, marginTop: Platform.OS === 'ios' ? 10 : 10, borderColor: '#6de3dc', borderWidth: 2, borderRadius: 30}}
/>
<View style={{flexDirection: 'row', justifyContent: 'center', alignItems: 'center', marginTop: 5}}>
<Ionicons
name='ios-star'
color='#eec400'
size={14}
/>
<Ionicons
name='ios-star'
color='#eec400'
size={14}
/>
<Ionicons
name='ios-star'
color='#eec400'
size={14}
/>
<Ionicons
name='ios-star'
color='#eec400'
size={14}
/>
<Ionicons
name='ios-star'
color='#eec400'
size={14}
/>
</View>
</View>
</View>
<View style={{flexDirection: 'column', backgroundColor: '#e6fffe', marginTop: Platform.OS === 'ios' ? 10 : 10, flex: 0.5}}>
<View style={{flexDirection: 'row', flex: 0.5}}>
<View style={{flex: 0, alignSelf: 'center'}}>
<Text style={{fontSize: 16, fontWeight: '700'}}>
eamon.white
</Text>
</View>
</View>
</View>
</View>
<View style={{flex: 0, marginBottom: 5, backgroundColor: '#e6fffe'}}>
<Text
style={{
width: 280,
flex: 0,
backgroundColor: '#e6fffe',
paddingLeft: 5,
borderWidth: 0,
borderRadius: 4,
color: '#000'
}}>
{this.state.messageFromSender}
</Text>
</View>
</View>
<View style={{ flexDirection: 'column', flex: 1, marginBottom: 5 }}>
<Text
style={{
flex: 0,
width: Dimensions.get('window').width,
color: 'white',
fontWeight: '700',
marginTop: 5,
marginBottom: 5
}}>
Date(s) Needed:
</Text>
{this.showCalendar()}
</View>
<View style={{ flexDirection: 'column', flex: 0.1, marginBottom: 10 }}>
<TextInput
style={{
width: 280,
flex: 1,
borderColor: 'gray',
borderWidth: 1,
backgroundColor: '#ffffff',
paddingLeft: 5,
borderRadius: 4,
}}
onChangeText={text => this.setState({ message: text })}
value={this.state.message}
multiline={true}
numberOfLines={2}
onFocus={this.animateUp}
placeholder='Type a message...'
/>
</View>
<View style={{ flex: 0.1, borderRadius: 4, borderWidth: 0, marginBottom: 10 }}>
<TouchableOpacity
activeOpacity={1}
style={{
backgroundColor: this.state.rentButtonBackground,
flex: 1,
justifyContent: 'center',
alignItems: 'center',
width: 280,
borderRadius: 4,
borderWidth: 0,
}}
onPress={() => {
}}>
<Text
style={{
backgroundColor: this.state.rentButtonBackground,
textAlign: 'center',
color: 'white',
fontWeight: '900',
fontSize: 18,
borderRadius: 4,
borderWidth: 0,
}}>
RESPOND
</Text>
</TouchableOpacity>
</View>
<View style={{ flex: 0.1, borderRadius: 4, borderWidth: 0, marginBottom: 10 }}>
<TouchableOpacity
activeOpacity={1}
style={{
backgroundColor: this.state.rentButtonBackground,
flex: 1,
justifyContent: 'center',
alignItems: 'center',
width: 280,
borderRadius: 4,
borderWidth: 0,
}}
onPress={() => {
}}>
<Text
style={{
backgroundColor: this.state.rentButtonBackground,
textAlign: 'center',
color: 'white',
fontWeight: '900',
fontSize: 18,
borderRadius: 4,
borderWidth: 0,
}}>
ACCEPT
</Text>
</TouchableOpacity>
</View>
<View style={{ flex: 0.1, borderRadius: 4, borderWidth: 0 }}>
<TouchableOpacity
activeOpacity={1}
style={{
backgroundColor: this.state.rentButtonBackground,
flex: 1,
justifyContent: 'center',
alignItems: 'center',
width: 280,
borderRadius: 4,
borderWidth: 0,
}}
onPress={() => {
}}>
<Text
style={{
backgroundColor: this.state.rentButtonBackground,
textAlign: 'center',
color: 'white',
fontWeight: '900',
fontSize: 18,
borderRadius: 4,
borderWidth: 0,
}}>
DECLINE
</Text>
</TouchableOpacity>
</View>
</View>
</Animated.View>
</TouchableWithoutFeedback>
);
render() {
//console.log('this.state._markedDates in render:', this.state._markedDates);
return (
<Modal
animationType="slide"
transparent={true}
visible={this.state.modalVisible} //THIS NEEDS TO BE TRUE WHEN I COME BACK
onBackdropPress ={() => {/*console.log("backdrop pressed");*/ if(!this.state.keyboardOpen) {this.setModalVisible(false)} else {Keyboard.dismiss()}}}>
{this._renderModalContent()}
</Modal>
)
}
Home
路由从 App.js
导航到,它正在接收推送通知...如果导航发生或不发生,对推送通知的响应是委托的内容。这是导航的样子:
App.js
export default class App extends React.Component {
constructor() {
super();
}
componentDidMount() {
this.messageListener = firebase.messaging().onMessage((message: RemoteMessage) => {
console.log(message);
// prevent infite look
//if (!message.local_notification) {
let count = 1;
let string = '';
for(date of JSON.parse(message.data.dates)) {
if(count == JSON.parse(message.data.dates).length)
string += date;
else {
string += date+'\n';
}
count++;
}
// Process your message as required
Alert.alert(
'New Rental Inquiry',
'Dates Requested:\n\n'+string,
[
{text: 'RESPOND', onPress: () => {
console.log("message.data:", message.data);
console.log("this.props.ref:", this.props.ref);
//NavigationService.reset('Home', { data: JSON.parse(JSON.stringify(message.data)) })
NavigationService.navigate('Home', { data: JSON.parse(JSON.stringify(message.data)) });
}},
{text: 'IGNORE', onPress: () => console.log('IGNORE Pressed')},
],
{ cancelable: false }
)
//}
});
}
....
我直接从 React Native 文档中获取 NavigationService
,如果你不想看到它是如何工作的,你可以 google 它,但它只是导航你如何使用 this.props.navigation.navigate()
.
更新
我可能发现了这个错误,当我按下模态的背景时,我有效地将它的 visible
属性设置为 false,这样当 RespondToInquiry
再次出现时(我假设由于我所看到的行为,它从未被卸载过),模态不可见。将模式设置为可见似乎有点棘手,因为 RespondToInquiry
似乎没有被卸载(即我不能把它放在 componentWillUnmount
中)。在 RespondToInquiry
中,在 state
变量中 - 我将模式的默认设置设置为可见,因此当我从它导航时它不能被卸载,即使它不在任何导航堆栈中。此外,在上方 - 您可以看到我的 didFocus
侦听器,它更改了负责呈现 RespondToInquiry
.
的条件
我将此添加到 HomeScreen.js
的 componentDidMount
:
this._sub2 = this.props.navigation.addListener(
'didBlur',
() => {
console.log('in didBlur for HomeScreen');
this.setState({info: this.props.navigation.getParam('data', '')})
this.setState({showRespondTo: false});
}
);
从本质上讲,似乎条件再次被识别为真,它必须被重置 - 对此的解释会很好。
我还遇到了模态未呈现的问题,这是由于为了验证目的在设置状态后放置
windows.alert()
调用。
因此通过删除警报解决。
这是 render
函数,它应该不包括 RespondToInquiry
组件:
HomeScreen.js
componentDidMount() {
console.log('key for stack navigator:',this.props.navigation.dangerouslyGetParent().state.key);
this._sub = this.props.navigation.addListener(
'didFocus',
() => {
console.log('in didFocus for HomeScreen');
if(this.props.navigation.getParam('data', '') != '') {
console.log('showRespondTo fired.');
this.setState({info: this.props.navigation.getParam('data', '')})
this.setState({showRespondTo: true});
}
}
);
....
}
render() {
console.log('in render of HomeScreen',this.props.navigation.getParam('data', ''),this.state.showRespondTo);
return (
<View style={{flex:1}}>
{this.state.showRespondTo && this.returnRespond()}
<TouchableWithoutFeedback onPress={Keyboard.dismiss}>
<View style={styles.container}>
<MultiSelectList
style={{backgroundColor: '#ffe4c4'}}
data={this.state.items}
renderItem={this.renderListItems}
numColumns={2}
contentContainerStyle={{}}
onEndReachedThreshold={0.5}
maxToRenderPerBatch={2}
initialNumToRender={4}
ListHeaderComponent={this.renderHeader}
getItemLayout={(data, index) => (
{length: Dimensions.get('window').height/2, offset: Dimensions.get('window').height/2 * index, index}
)}
backgroundColor={this.state.backgroundColor}
/>
</View>
</TouchableWithoutFeedback>
</View>
);
}
console.log('in render of HomeScreen',this.props.navigation.getParam('data', ''),this.state.showRespondTo);
的输出是:
in render of HomeScreen (2)
{tempId: "1537747945332", message: "Hi, I would like to rent an item from you.", dates: "[]"}
true
所以你可以看到 this.state.showRespondTo
是真的,所以它应该呈现 RespondToInquiry
,但它没有。
这就是 RespondToInquiry.js
的样子:
_renderModalContent = () => (
<TouchableWithoutFeedback onPress={() => {if(this.state.keyboardOpen) {Keyboard.dismiss()}}}>
<Animated.View
style={{
paddingTop: 5,
paddingBottom: 10,
paddingLeft: 10,
paddingRight: 10,
marginTop: this.state.yPosition,
marginBottom: this.state.yPositionPositive,
flex: 1,
marginLeft: (Dimensions.get('window').width - 300) / 4,
backgroundColor: 'rgba(0,0,0,0.8)',
width: 300,
borderRadius: 4,
borderWidth: 0,
}}>
<View style={{ flexDirection: 'column', justifyContent: 'space-between', flex: 1 }}>
<View style={{flexDirection: 'column', justifyContent: 'space-between', flex: 0, backgroundColor: '#e6fffe', marginTop: 5}}>
<View style={{flex: 0, backgroundColor: '#e6fffe', flexDirection: 'row', justifyContent: 'center', alignItems: 'center', paddingBottom: 10, borderBottomColor: '#6de3dc', borderBottomWidth: 0}}>
<View style={{justifyContent: 'center', alignItems: 'center', flex: 0.5}}>
<View style={{flexDirection: 'column', justifyContent: 'space-between'}}>
<Image
source={require('../assets/billythekid2.jpg')}
style={{height: 60, width: 60, marginTop: Platform.OS === 'ios' ? 10 : 10, borderColor: '#6de3dc', borderWidth: 2, borderRadius: 30}}
/>
<View style={{flexDirection: 'row', justifyContent: 'center', alignItems: 'center', marginTop: 5}}>
<Ionicons
name='ios-star'
color='#eec400'
size={14}
/>
<Ionicons
name='ios-star'
color='#eec400'
size={14}
/>
<Ionicons
name='ios-star'
color='#eec400'
size={14}
/>
<Ionicons
name='ios-star'
color='#eec400'
size={14}
/>
<Ionicons
name='ios-star'
color='#eec400'
size={14}
/>
</View>
</View>
</View>
<View style={{flexDirection: 'column', backgroundColor: '#e6fffe', marginTop: Platform.OS === 'ios' ? 10 : 10, flex: 0.5}}>
<View style={{flexDirection: 'row', flex: 0.5}}>
<View style={{flex: 0, alignSelf: 'center'}}>
<Text style={{fontSize: 16, fontWeight: '700'}}>
eamon.white
</Text>
</View>
</View>
</View>
</View>
<View style={{flex: 0, marginBottom: 5, backgroundColor: '#e6fffe'}}>
<Text
style={{
width: 280,
flex: 0,
backgroundColor: '#e6fffe',
paddingLeft: 5,
borderWidth: 0,
borderRadius: 4,
color: '#000'
}}>
{this.state.messageFromSender}
</Text>
</View>
</View>
<View style={{ flexDirection: 'column', flex: 1, marginBottom: 5 }}>
<Text
style={{
flex: 0,
width: Dimensions.get('window').width,
color: 'white',
fontWeight: '700',
marginTop: 5,
marginBottom: 5
}}>
Date(s) Needed:
</Text>
{this.showCalendar()}
</View>
<View style={{ flexDirection: 'column', flex: 0.1, marginBottom: 10 }}>
<TextInput
style={{
width: 280,
flex: 1,
borderColor: 'gray',
borderWidth: 1,
backgroundColor: '#ffffff',
paddingLeft: 5,
borderRadius: 4,
}}
onChangeText={text => this.setState({ message: text })}
value={this.state.message}
multiline={true}
numberOfLines={2}
onFocus={this.animateUp}
placeholder='Type a message...'
/>
</View>
<View style={{ flex: 0.1, borderRadius: 4, borderWidth: 0, marginBottom: 10 }}>
<TouchableOpacity
activeOpacity={1}
style={{
backgroundColor: this.state.rentButtonBackground,
flex: 1,
justifyContent: 'center',
alignItems: 'center',
width: 280,
borderRadius: 4,
borderWidth: 0,
}}
onPress={() => {
}}>
<Text
style={{
backgroundColor: this.state.rentButtonBackground,
textAlign: 'center',
color: 'white',
fontWeight: '900',
fontSize: 18,
borderRadius: 4,
borderWidth: 0,
}}>
RESPOND
</Text>
</TouchableOpacity>
</View>
<View style={{ flex: 0.1, borderRadius: 4, borderWidth: 0, marginBottom: 10 }}>
<TouchableOpacity
activeOpacity={1}
style={{
backgroundColor: this.state.rentButtonBackground,
flex: 1,
justifyContent: 'center',
alignItems: 'center',
width: 280,
borderRadius: 4,
borderWidth: 0,
}}
onPress={() => {
}}>
<Text
style={{
backgroundColor: this.state.rentButtonBackground,
textAlign: 'center',
color: 'white',
fontWeight: '900',
fontSize: 18,
borderRadius: 4,
borderWidth: 0,
}}>
ACCEPT
</Text>
</TouchableOpacity>
</View>
<View style={{ flex: 0.1, borderRadius: 4, borderWidth: 0 }}>
<TouchableOpacity
activeOpacity={1}
style={{
backgroundColor: this.state.rentButtonBackground,
flex: 1,
justifyContent: 'center',
alignItems: 'center',
width: 280,
borderRadius: 4,
borderWidth: 0,
}}
onPress={() => {
}}>
<Text
style={{
backgroundColor: this.state.rentButtonBackground,
textAlign: 'center',
color: 'white',
fontWeight: '900',
fontSize: 18,
borderRadius: 4,
borderWidth: 0,
}}>
DECLINE
</Text>
</TouchableOpacity>
</View>
</View>
</Animated.View>
</TouchableWithoutFeedback>
);
render() {
//console.log('this.state._markedDates in render:', this.state._markedDates);
return (
<Modal
animationType="slide"
transparent={true}
visible={this.state.modalVisible} //THIS NEEDS TO BE TRUE WHEN I COME BACK
onBackdropPress ={() => {/*console.log("backdrop pressed");*/ if(!this.state.keyboardOpen) {this.setModalVisible(false)} else {Keyboard.dismiss()}}}>
{this._renderModalContent()}
</Modal>
)
}
Home
路由从 App.js
导航到,它正在接收推送通知...如果导航发生或不发生,对推送通知的响应是委托的内容。这是导航的样子:
App.js
export default class App extends React.Component {
constructor() {
super();
}
componentDidMount() {
this.messageListener = firebase.messaging().onMessage((message: RemoteMessage) => {
console.log(message);
// prevent infite look
//if (!message.local_notification) {
let count = 1;
let string = '';
for(date of JSON.parse(message.data.dates)) {
if(count == JSON.parse(message.data.dates).length)
string += date;
else {
string += date+'\n';
}
count++;
}
// Process your message as required
Alert.alert(
'New Rental Inquiry',
'Dates Requested:\n\n'+string,
[
{text: 'RESPOND', onPress: () => {
console.log("message.data:", message.data);
console.log("this.props.ref:", this.props.ref);
//NavigationService.reset('Home', { data: JSON.parse(JSON.stringify(message.data)) })
NavigationService.navigate('Home', { data: JSON.parse(JSON.stringify(message.data)) });
}},
{text: 'IGNORE', onPress: () => console.log('IGNORE Pressed')},
],
{ cancelable: false }
)
//}
});
}
....
我直接从 React Native 文档中获取 NavigationService
,如果你不想看到它是如何工作的,你可以 google 它,但它只是导航你如何使用 this.props.navigation.navigate()
.
更新
我可能发现了这个错误,当我按下模态的背景时,我有效地将它的 visible
属性设置为 false,这样当 RespondToInquiry
再次出现时(我假设由于我所看到的行为,它从未被卸载过),模态不可见。将模式设置为可见似乎有点棘手,因为 RespondToInquiry
似乎没有被卸载(即我不能把它放在 componentWillUnmount
中)。在 RespondToInquiry
中,在 state
变量中 - 我将模式的默认设置设置为可见,因此当我从它导航时它不能被卸载,即使它不在任何导航堆栈中。此外,在上方 - 您可以看到我的 didFocus
侦听器,它更改了负责呈现 RespondToInquiry
.
我将此添加到 HomeScreen.js
的 componentDidMount
:
this._sub2 = this.props.navigation.addListener(
'didBlur',
() => {
console.log('in didBlur for HomeScreen');
this.setState({info: this.props.navigation.getParam('data', '')})
this.setState({showRespondTo: false});
}
);
从本质上讲,似乎条件再次被识别为真,它必须被重置 - 对此的解释会很好。
我还遇到了模态未呈现的问题,这是由于为了验证目的在设置状态后放置 windows.alert()
调用。
因此通过删除警报解决。