react-native: Modal: Refresh (via dev menu) does not tear down

Is this a bug report?

yes

Have you read the Contributing Guidelines?

kind of

Environment

Environment: OS: Windows 10 Node: 9.0.0 Yarn: 1.3.2 npm: 5.5.1 Watchman: Not Found Xcode: N/A Android Studio: Version 3.0.0.0 AI-171.4408382

Packages: (wanted => installed) react: 16.2.0 => 16.2.0 react-native: 0.53.0 => 0.53.0

Target Platform: Android 7.0 on Samsung Galaxy S5

Steps to Reproduce

  1. create app and launch with react-native run-android
  2. trigger state which causes a modal to show
  3. launch the dev menu (via shake or keycode)
  4. select refresh

Expected Behavior

The app closes the modal and refreshes

Actual Behavior

The app presumably refreshes, but the modal stays on top and cannot be closed

Reproducible Demo


import React, { Component } from 'react';
import { Text, View, Button, Modal, StyleSheet } from 'react-native';

export default class MyComponent extends Component {
  state = {
    modalVisible: false,
  };

  openModal() {
    this.setState({modalVisible:true});
  }

  closeModal() {
    this.setState({modalVisible:false});
  }

  render() {
    return (
        <View style={styles.container}>
          <Modal
              visible={this.state.modalVisible}
              animationType={'slide'}
              onRequestClose={() => this.closeModal()}
          >
            <View style={styles.modalContainer}>
              <View style={styles.innerContainer}>
                <Text>This is content inside of modal component</Text>
                <Button
                    onPress={() => this.closeModal()}
                    title="Close modal"
                >
                </Button>
              </View>
            </View>
          </Modal>
          <Button
              onPress={() => this.openModal()}
              title="Open modal"
          />
        </View>
    );
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
  },
  modalContainer: {
    flex: 1,
    justifyContent: 'center',
    backgroundColor: 'grey',
  },
  innerContainer: {
    alignItems: 'center',
  },
});

About this issue

  • Original URL
  • State: closed
  • Created 6 years ago
  • Reactions: 117
  • Comments: 77 (10 by maintainers)

Commits related to this issue

Most upvoted comments

Confirming, still an issue in RN 0.60.4

Still an issue on react-native 0.59.3

Are you guys kidding that, after so many RN versions and month since this issue was open, nobody made a fix?

Can confirm this is happening on Android and iOS using react-native 0.55.4

@PiotrKujawa Actually the pr you mentioned is not the fix, but the cause!

The root cause is the removal of this line

  public void onHostPause() {	  
-    // We dismiss the dialog and reconstitute it onHostResume
-    dismiss();	
  }

When we do reload, actually we do a pause, so the dismiss() in onHostPause() can be triggered. But since this pr merged into 0.53, there was no dismiss anymore. This bug emerged since then.

After adding that line back, now the modal can tear down normally modal

@mdvacca Could you recall why you removed this line? I could not see how that was related to Modal not disappearing when navigating to another activity? Do you expect the modal should persist when navigation to another activity?

So… what’s the workaround here? This issue is 6 months old and its still happening on 56.0.

Our project just updated from RN 0.50 to 0.56. I can confirm that this has become a frustrating new issue for our app.

I have the same problem.

“react-native”: “0.56.0”

I can confirm this is happening on both Android and iOS on RN 54

Confirming, still an issue in RN 0.60.4

That fix is also in 0.55.4, and the problem remains (Android emulation at least). It’s a blocker for hot/live reloading, therefore for any decent development environment. Can’t use this package until it’s fixed.

still an issue in react-native 0.55.4

Does anyone have a concrete solution for this? Am using RN 0.58.3

I can also confirm this still happens on 0.56.

Can confirm this still happens on 0.55.4, both on a physical Xiaomi Redmi Note 4 (Android 7.0/MIUI Global 9.5) and an emulated API 23 device.

On emulator refresh, it appears it rendering a duplicate modal. I have to close the app in the emulator and relaunch to work around this.

I am still seeing this issue as of 0.57.1 (Android only, iOS will tears it down properly)

@hongdung6992 The fix will land on 0.62-rc1

On emulator refresh, it appears it rendering a duplicate modal. I have to close the app in the emulator and relaunch to work around this.

same here, “react-native”: “0.59.8”,

Still occurring in 0.57.0

  React Native Environment Info:
    System:
      OS: Linux 4.15 Ubuntu 16.04.5 LTS (Xenial Xerus)
      CPU: x64 Intel(R) Core(TM) i7-7700 CPU @ 3.60GHz
      Memory: 204.00 MB / 15.54 GB
      Shell: 4.3.48 - /bin/bash
    Binaries:
      Node: 8.11.0 - ~/.nvm/versions/node/v8.11.0/bin/node
      Yarn: 1.9.4 - /usr/bin/yarn
      npm: 5.6.0 - ~/.nvm/versions/node/v8.11.0/bin/npm
      Watchman: 4.9.0 - /usr/local/bin/watchman
    SDKs:
      Android SDK:
        Build Tools: 23.0.1, 26.0.1, 26.0.2, 26.0.3, 27.0.0, 27.0.3
        API Levels: 16, 19, 22, 23, 26, 27, 28
    IDEs:
      Android Studio: 3.1 AI-173.4907809
    npmPackages:
      react: ^16.5.0 => 16.5.1 
      react-native: 0.57.0 => 0.57.0 
    npmGlobalPackages:
      create-react-native-app: 1.0.0
      react-native-cli: 2.0.1
      react-native-git-upgrade: 0.2.7

Is there any workaround? This also affects programmatic restarting on codepush updates for example.

This is also an issue for those of us using codepush. When the app refreshes the js bundle, the previous state modal still shows and completely locks the app.

please then somwone tell how to fix it

still facing this issue. Any updates ?

(The issue is present in Expo SDK v32.0.0 which is based on RN 0.57)

I’m confirming it as well on 0.57.8. Could someone pls advise as our App is likely to get this issue soon and might impact customers once one of the features for the modal goes live.

Confirming this is still an issue on the latest release, 0.57.8. Though the issue is very apparent when hot-reloading, it’s also still an issue with any sort of reload while the modal is open.

For now, I suggest using a js modal like react-native-root-modal instead of this one as a workaround.

I wrote this and it solves my issue on android, haven’t tried on ios yet.

import React from 'react'
import { Modal } from 'react-native'
type ExtractProps<
  TComponentOrTProps
> = TComponentOrTProps extends React.Component<infer TProps, any>
  ? TProps
  : TComponentOrTProps

export class UnMountingModal extends React.PureComponent<
  ExtractProps<Modal>,
  { mounted: boolean }
> {
  public state = { mounted: false }
  public componentDidMount() {
    this.setState({ mounted: true })
  }
  public componentWillUnmount() {
    this.setState({ mounted: false })
  }
  public render() {
    return (
      <Modal {...this.props} visible={this.state.mounted && this.props.visible}>
        {this.props.children}
      </Modal>
    )
  }
}

EDIT: this actually only appears to work on hot reaload, which is how i dev.

Still have this issue in RN 0.57.4 Why?!!

I’m also confirming this is still an issue on 0.57.8

TL;DR

No easy fix right now cause there is no proper mechanism to manage modals. And basically not worth the work to refactor the architecture only for this issue.


Ideally, modal should be notified when ReactContext was tear down. The current flow only deal with main rootviews and pure native modules, but modal was a non typical rootview, neither recorded in ReactInstanceManager nor in NativeModuleRegistry, so it is forgotten in the between. Actually some other native modules also forgot to handle instance destroyed event, like Alert(DialogModule). If you enable live reload and fire an alert action, then modify the source code, you can see the Alert window also hang on the screen after reload. (It is a pure native module and can override on react instance destroyed event but it forgot) @shergin Curious that has the new architecture considered these situations? IMHO,

  1. the react instance events should be notified to viewmanagers as well, or,
  2. there should be another list to manage special views outside of main rootviews in instance manager

I have confirmed .54, .55 , .56. Still has this issues.

I guess here’s the fix https://github.com/facebook/react-native/commit/e5c2a66 and will be available in 0.56