Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

804
Views
React Native: Opening a Modal from inside another Modal doesn't work in iOS

I have a Dropdown component which is just a React Native Modal positioned next to a toggle - the Modal allows me to make the whole background a Pressable so I can close the dropdown when any area outside it is pressed.

The items inside the dropdown menu each have an onPress prop which performs a given function while also closing the dropdown itself. This works great, except when I want to use the onPress event to open another react-native Modal.

Here's a (simplified) example:

<>
  // Custom component that renders a react-native Modal
  <Dropdown
    items={[
      { label: "Press to open a Modal", onPress: () => setIsModalOpen(true) }
    ]}
  />

  // Another react-native Modal
  <Modal visible={isModalOpen}>
    ...
  </Modal>
</>

This works as expected on the web - the Dropdown's Modal closes and the other Modal opens at the same time. However, on iOS, the second Modal never opens, and the app actually becomes completely unresponsive until I restart it from the Metro builder.

I've seen other questions on Stack Overflow that mention "opening a modal from inside another modal", but the existing questions all seem to concern nested modals. In my case, we aren't actually trying to nest modals - the second modal should open as the first one closes. The iOS app seems to just not render the second modal, even though I can verify through the console that the isModalOpen boolean is getting set to true.

I'm beginning to think this is actually a bug with React Native itself, but figured I'd check here in case it's a known issue, maybe with event bubbling or something?

about 4 years ago · Juan Pablo Isaza
3 answers
Answer question

0

You can use InteractionManager inside your first modal useEffect. that guarantees your second modal will open after the first modal animation is finished.

InteractionManager.runAfterInteractions(() => {
   // ...long-running synchronous task...
 });

more detail: https://reactnative.dev/docs/interactionmanager

about 4 years ago · Juan Pablo Isaza Report

0

So at the end of the day, the issue is that React Native simply won't show two modals at the same time - this limitation applies even if you're trying to open a new modal while the previous one's closing animation is still finishing up.

It seems like some people handle this with a timeout, but that proved unreliable in my testing. A timeout also relies on a magic number, when the crux of the issue is that the modal has yet to unmount before opening a new one.

To solve this, I added a state variable called queuedPress to my Dropdown menu's context provider that stores the onPress function from the menu item that was just pressed. I also added an afterClose callback that runs when the Dropdown menu's closing animation completes. When a Dropdown item is pressed, I store its onPress function, then afterClose handles the actual call. This ensures the onPress is queued for as long as the animation takes to complete, so the modal opened from within that onPress will be guaranteed to open after the dropdown is already closed.

Depending on your code your implementation might vary wildly, but in my case this is another situation where useContext has saved the day. Any solution that limits the number of open modals to 1 should work.

about 4 years ago · Juan Pablo Isaza Report

0

This's a known limitation in react-native

but as a workaround

  1. you can use setTimeout for the 2nd modal after closing the 1st modal
  2. use conditional rendering so it registers(mount/unmount) to the dom the 2nd modal based on the visibility
import React, {useCallback, useState} from 'react';
import {Button, Modal, Text, View} from 'react-native';

const App = () => {
  const [is1stModalVisible, setIs1stModalVisible] = useState(false);
  const [is2ndModalVisible, setIs2ndModalVisible] = useState(false);

  const onOpen2ndModal = useCallback(() => {
    // closes the 1st modal
    setIs1stModalVisible(false);
    // open the 2nd modal
    setTimeout(
      () => {
        setIs2ndModalVisible(true);
      },
      // any small number will do, maybe animation duration
      100,
    );
  }, []);

  return (
    <View>
      <Button
        title="Open 1st modal"
        onPress={() => setIs1stModalVisible(true)}
      />

      <Modal visible={is1stModalVisible}>
        <Text>Modal 1 content</Text>
        <Button title="Open 2nd modal" onPress={onOpen2ndModal} />
      </Modal>
      {is2ndModalVisible ? (
        <Modal visible={is2ndModalVisible}>
          <Text>Modal 2 content</Text>
          <Button
            title="Close 2nd modal"
            onPress={() => setIs2ndModalVisible(false)}
          />
        </Modal>
      ) : null}
    </View>
  );
};

export default App;
about 4 years ago · Juan Pablo Isaza Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!