8

I'm experiencing an issue where every time I dismiss a modal, action sheet, or Alert in our React Native app, the app completely freezes and can't be interacted with.

Navigating to a new stack or clicking buttons doesn't repro.

I have to kill the app and restart to interact again. Reloading the app via the packager does not help.

We have code that automatically shows a new modal when one is dismissed and that actually works - the modal is interactable. So it seems that only underlying content is frozen, as if there's still a modal over the top but it's invisible.

The crazy thing is that this is reproing in previous known good branches. So something must have changed with local config/cache, but I can't figure out what. I've re-cloned the repo, cleared the watchman/packager/yarn caches, wiped the simulator of all data. Nothing is fixing the issue.

There are also no logs in the packager, xcode, or Flipper indicating what might be going wrong.

Using react-native-modal, @expo/react-native-action-sheet, and built-in React Native Alert (not using general Expo framework though). I've upgraded these libraries to the latest version.

Running out of ideas. Where else can I look here?


Update: Super-minimal code repros. This modal auto-shows, auto-dismisses, and then the button is unpressable. Removing the modal from the code makes the button pressable.

function TestApp() {
  const [isVisible, setVisible] = useState(true);
  return (
    <>
      <TouchableOpacity style={{ padding: 80 }} delayPressIn={0}>
        <Text>Touch</Text>
      </TouchableOpacity>
      <Modal isVisible={isVisible} onShow={() => setVisible(false)}>
        <Text>Foo</Text>
      </Modal>
    </>
  );
}

The same happens if I add a minimal alert call instead of a modal. In this case I show another alert after 5 seconds which is interactable. Only popovers are interactable - e.g. alerts and modals.

  useEffect(() => Alert.alert("alert"), []);
  useEffect(() => {
    setTimeout(() => Alert.alert("5s alert"), 5000);
  }, []);

Update #2

It looks like each new "popover" style UI makes any previous UI un-interactable.

If I dismiss the first Alert as above, then I can't interact with the underlying TouchableOpacity, but I can interact with the second (5-second) Alert.

However if I do not dismiss the first Alert and the second Alert pops over, I can only dismiss the second alert and not interact with the first alert which remains frozen.

Freewalker
  • 6,329
  • 4
  • 51
  • 70
  • 1
    is really difficult to tell without a repro sample, what i have experience with modals in ios is that if you open a modal without completely being sure of the other modal being closed then the app freezes and there is no response, but as i already told you not sure if this could be your case without seeing some code sample. – Charlie Jul 24 '20 at 00:03
  • Thanks - this was with code already working for a long time, so it's hard to see what could be coded incorrectly. The code was actually working when I came in this morning - I think "restart the computer" probably actually is the fix here, strangely. The app may also not have been picking up changes I was making to debug at the end of the day, like console.logs, which is another clue. – Freewalker Jul 24 '20 at 15:23
  • Now reproing again including after a full computer reset and it's picking up changes... going to try and diagnose further. – Freewalker Jul 24 '20 at 16:04
  • Your "isVisible" `useState` logic feels inverted. Going by what you've pasted above, it means that the modal will be shown at first render, and then when it is shown, the `onShow` function (called after the modal is shown) will attempt to hide it again immediately. – Labu Aug 01 '20 at 12:10
  • @Labu yes, this is just as a test case - I'm seeing what happens when it shows and hides. Same behavior as pressing a button to close it after showing. – Freewalker Aug 04 '20 at 16:56

3 Answers3

11

For me the freezing happens only when Flipper layout plugin is active for my app. Disabled the layout plugin, restarted Flipper, restarted my app and the freezing problem was gone.

lirkki
  • 221
  • 1
  • 8
  • Holy cow. Thank you, thank you, thank you. That explains why nothing I did in code seemed to affect it, and why it would pop up even in code that was already well-tested and working! – Freewalker Aug 06 '20 at 18:47
  • Please note that there is an open issue for this at Flipper, but we still are waiting for someone to create small reproduction project https://github.com/facebook/flipper/issues/1399#issuecomment-670133415 – mweststrate Aug 25 '20 at 11:11
  • Instead of disabling Flipper, this solution is now possible: "in ios/Podfile change `use_flipper!` to `use_flipper!('Flipper' => '0.54.0')` and run `pod install --repo-update` afterwards in ios dir." See: https://github.com/facebook/flipper/issues/1399#issuecomment-681902393 – Freewalker Feb 02 '21 at 04:37
0

Generally Modals are usually accompanied with an overlay layer/background mask. When you dismiss a modal, are you also sure that you are dismissing the overlay layer, because if there is any transparent layer, that can block the touches on other controls.

Vijay122
  • 884
  • 8
  • 12
  • Thank you - there shouldn't be any necessary extra work to dismiss the underlying layer. The code here is very simple and just instructs the RN modal to hide, which should take care of "overlay" logic as an implementation detail (it always has before). – Freewalker Aug 04 '20 at 16:57
0

This is caused by an outdated Flipper version being shipped. Replace use_flipper! in the ios/Podfile with use_flipper!('Flipper' => '0.54.0'), and run pod install should fix the issue.

mweststrate
  • 4,890
  • 1
  • 16
  • 26