Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

React-Native Controlled Modal Freezing

Tags:

react-native

Disclaimers: Only can test on iPhone emulator atm. React-Native 0.49 Mac OSX High Sierra

I want to create a modal which gets its props from a parent component. As below:

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>
);

This is the parent example:

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

When I click the show modal button the modal pops-up as expected but when I click closeModal then the modal disappears and reappears again but this time I cannot interact with it, the UI seems as if it is frozen, I have to then restart the emulator.

If I copy and paste the code straight from the React-Native docs: https://facebook.github.io/react-native/docs/modal.html The modal works fine. It is a self-contained component though.

Any help/advice would be much appreciated.

Regards, Emir

like image 476
eGlu Avatar asked Nov 20 '17 09:11

eGlu


4 Answers

After painfully rebuilding the component from scratch I see there was a unsuspected culprit:

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

When I removed this code the modal worked fine but when I added it back it froze when I tried to close. This seems to be some animation conflict in iOS cant confirm for Android.

When I added a timeout of 1000ms the screen revealed a little more before it froze again.

So for now if someone has the same issue look for multiple animations being called.

Hope this helps someone, and if you have a better way of solving it please do let me know.

Regards, Emir

like image 115
eGlu Avatar answered Oct 22 '22 15:10

eGlu


This is a know issue and nothing to do with your code.

See here: https://github.com/facebook/react-native/issues/16895

like image 45
Walter Monecke Avatar answered Oct 22 '22 14:10

Walter Monecke


Very late, but issue still exist in latest version, And only solution i found is make different views in render method.

one for modal and one for other component.

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>
    );
  }
}
like image 1
Sagar Chavada Avatar answered Oct 22 '22 15:10

Sagar Chavada


Make sure that your <Modal/> is wrapped in a <View/>.

like image 1
Christopher Chalfant Avatar answered Oct 22 '22 15:10

Christopher Chalfant