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.jscomponentDidMount

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()
调用。
因此通过删除警报解决。