React-Native控制模态冻结

时间:2017-11-20 09:16:56

标签: react-native

免责声明: 只能在iPhone模拟器上测试atm。 React-Native 0.49 Mac OSX High Sierra

我想创建一个从父组件获取道具的模态。 如下:

const Modal = ({ showModal, closeModal }) => (
  <Modal
    animationType="slide"
    transparent={false}
    visible={showModal}
    onRequestClose={() => {alert("Modal has been closed.")}}
    >
   <View style={{marginTop: 22}}>
     <Text>Hello World!</Text>
     <TouchableHighlight onPress={() => closeModal() }>
        <Text>Hide Modal</Text>
     </TouchableHighlight>
   </View>
  </Modal>
);

这是父示例:

<View>
  <Modal
    showModal={this.state.showModal}
    closeModal={() => this.setState({ showModal: false })}
  />
  <ScrollView>
      {elements.map(element => {
        return (
          <Card key={element.id}>  
            <Badge onPress={() => this.setState({ showModal: true })>
              <Text>Show</Text>
            </Badge>
          </Card>
        );
      })}
  </ScrollView>
</View>

当我单击show modal按钮时,模式弹出按预期弹出,但当我单击closeModal然后模态消失并再次出现但这次我无法与它交互,UI看起来好像被冻结了,我必须然后重启模拟器。

如果我直接从React-Native文档复制并粘贴代码: https://facebook.github.io/react-native/docs/modal.html 模态工作正常。它虽然是一个独立的组件。

非常感谢任何帮助/建议。

此致 埃米尔

6 个答案:

答案 0 :(得分:1)

从头开始痛苦地重建组件后,我发现有一个未曾预料到的罪魁祸首:

componentWillUpdate() {
    UIManager.setLayoutAnimationEnabledExperimental && UIManager.setLayoutAnimationEnabledExperimental(true);
    LayoutAnimation.easeInEaseOut();
  }

当我删除此代码时,模态工作正常,但当我将其添加回来时,当我试图关闭时它冻结了。这似乎是iOS中的一些动画冲突,无法确认Android。

当我添加1000毫秒的超时时,屏幕再次显示出来之前会再次冻结。

所以现在如果有人遇到同样的问题,请查找被调用的多个动画。

希望这有助于某人,如果你有更好的解决方法,请告诉我。

此致 埃米尔

答案 1 :(得分:1)

这是一个已知问题,与您的代码无关。

见这里:https://github.com/facebook/react-native/issues/16895

答案 2 :(得分:1)

很晚了,但是最新版本仍然存在问题,而我发现的唯一解决方案是在渲染方法中进行不同的视图。

一个用于模式,另一个用于其他组件。

render() {
    if (showErrorModal) {
      return (
          <ModalError message={message} visible={showErrorModal} handleBack={this.handleBack} />
      );
    }

    return (
        <ScrollView style={{ flex: 1 }}>
          <View style={{ padding: 10, paddingVertical: 20 }}>
            {!active ? this.fieldlabel() : this.fieldSelect()}
          </View>

        // remove this one, do not use here. it will block the UI
        {* <ModalError message={message} visible={showErrorModal} handleBack={this.handleBack} /> *}
        </ScrollView>
    );
  }
}

答案 3 :(得分:0)

在您的父组件中,创建一个函数会将showModal设置为false

<强>父

closeModal = () => {
  this.setState({
    showModal: false
  });
}

然后你需要通过道具将它传递给你的Modal

<Modal showModal={this.state.showModal} closeModal={this.closeModal} />

Modal内,更改: <TouchableHighlight onPress={() => this.closeModal() }>

要: <TouchableHighlight onPress={closeModal}>

答案 4 :(得分:0)

为什么你使用this.closeModal()?使用你从道具中得到的那个,即closeModal()。

<TouchableHighlight onPress={() => closeModal() }>

答案 5 :(得分:0)

确保将<Modal/>包裹在<View/>中。