【问题标题】:React Native - Modal not renderingReact Native - 模态不渲染
【发布时间】:2023-03-22 21:12:01
【问题描述】:

这是 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,如果你不想看到它是如何工作的,可以用谷歌搜索它,但它只是像使用 this.props.navigation.navigate() 一样导航。

更新

我可能发现了这个错误,当我按下模式的背景时,我有效地将其 visible 属性设置为 false,以便当 RespondToInquiry 再次出现时(我假设它从未被卸载,因为我看到的行为),模态是不可见的。将模式设置为可见似乎有点棘手,因为RespondToInquiry 似乎没有被卸载(即我不能把它放在componentWillUnmount 中)。在RespondToInquiry 中,在state 变量中 - 我将模式的默认设置设置为可见,因此当我从它导航时它不能被卸载,即使它不在任何导航堆栈中。另外,在上面 - 你可以看到我的 didFocus 监听器,它改变了负责渲染 RespondToInquiry 的条件。

【问题讨论】:

    标签: javascript react-native navigation conditional rendering


    【解决方案1】:

    我将此添加到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});
          }
    );
    

    从本质上讲,条件似乎要再次被识别为真,它必须被重置 - 对此的解释会很好。

    【讨论】:

      【解决方案2】:

      我还遇到了模态未呈现的问题,这是由于在设置状态后放置
      windows.alert()
      调用以进行验证。
      因此通过删除警报解决了。

      【讨论】:

        猜你喜欢
        • 2018-04-14
        • 1970-01-01
        • 2019-11-25
        • 1970-01-01
        • 1970-01-01
        • 2018-07-01
        • 2021-09-20
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多