You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React Native iOS端关闭首个Modal后打开第二个Modal的问题

针对iOS端React Native多Modal切换问题的解决方案

以下是几个无需依赖setTimeout的可靠方案,解决关闭第一个Modal后打开第二个无响应的问题:

方案1:使用原生Modal的onDismiss回调(推荐)

React Native原生Modal组件在iOS平台提供了onDismiss回调,该回调会在Modal完全关闭(包括退场动画结束)时触发,刚好匹配你的需求。直接在第一个Modal上绑定此回调,在回调中打开第二个Modal即可。

示例代码:

import { useState } from 'react';
import { Modal, View, Button } from 'react-native';

const MultiModalDemo = () => {
  const [showFirstModal, setShowFirstModal] = useState(false);
  const [showSecondModal, setShowSecondModal] = useState(false);

  return (
    <View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
      <Button title="打开第一个Modal" onPress={() => setShowFirstModal(true)} />

      <Modal
        visible={showFirstModal}
        animationType="slide"
        onDismiss={() => setShowSecondModal(true)}
      >
        <View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
          <Button title="关闭第一个Modal" onPress={() => setShowFirstModal(false)} />
        </View>
      </Modal>

      <Modal visible={showSecondModal} animationType="slide">
        <View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
          <Button title="关闭第二个Modal" onPress={() => setShowSecondModal(false)} />
        </View>
      </Modal>
    </View>
  );
};

export default MultiModalDemo;

注:onDismiss仅iOS生效,Android可配合onRequestClose回调做兼容,保证跨平台行为一致。

方案2:状态监听 + requestAnimationFrame

通过监听第一个Modal的可见状态变化,当状态变为false时,用requestAnimationFrame将打开第二个Modal的操作推迟到下一次UI渲染周期,确保第一个Modal的退场动画完全结束后再执行后续操作,比setTimeout更贴合UI渲染机制,无固定延迟的隐患。

示例代码:

import { useState, useEffect } from 'react';
import { Modal, View, Button } from 'react-native';

const MultiModalDemo = () => {
  const [showFirstModal, setShowFirstModal] = useState(false);
  const [showSecondModal, setShowSecondModal] = useState(false);

  useEffect(() => {
    if (!showFirstModal) {
      const rafId = requestAnimationFrame(() => {
        setShowSecondModal(true);
      });
      return () => cancelAnimationFrame(rafId);
    }
  }, [showFirstModal]);

  return (
    <View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
      <Button title="打开第一个Modal" onPress={() => setShowFirstModal(true)} />

      <Modal visible={showFirstModal} animationType="slide">
        <View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
          <Button title="关闭第一个,打开第二个" onPress={() => setShowFirstModal(false)} />
        </View>
      </Modal>

      <Modal visible={showSecondModal} animationType="slide">
        <View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
          <Button title="关闭第二个Modal" onPress={() => setShowSecondModal(false)} />
        </View>
      </Modal>
    </View>
  );
};

export default MultiModalDemo;

方案3:基于react-native-modal库的状态监听

如果你使用的是第三方react-native-modal库,可通过监听其isVisible状态变化,结合requestAnimationFrame确保动画完成后再切换Modal,替代已移除的onModalHide回调。

示例代码:

import { useState, useEffect } from 'react';
import Modal from 'react-native-modal';
import { View, Button } from 'react-native';

const MultiModalDemo = () => {
  const [firstModalVisible, setFirstModalVisible] = useState(false);
  const [secondModalVisible, setSecondModalVisible] = useState(false);

  useEffect(() => {
    if (!firstModalVisible) {
      const rafId = requestAnimationFrame(() => {
        setSecondModalVisible(true);
      });
      return () => cancelAnimationFrame(rafId);
    }
  }, [firstModalVisible]);

  return (
    <View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
      <Button title="打开第一个Modal" onPress={() => setFirstModalVisible(true)} />

      <Modal isVisible={firstModalVisible}>
        <View style={{ padding: 20, backgroundColor: 'white', borderRadius: 10 }}>
          <Button title="关闭第一个,打开第二个" onPress={() => setFirstModalVisible(false)} />
        </View>
      </Modal>

      <Modal isVisible={secondModalVisible}>
        <View style={{ padding: 20, backgroundColor: 'white', borderRadius: 10 }}>
          <Button title="关闭第二个Modal" onPress={() => setSecondModalVisible(false)} />
        </View>
      </Modal>
    </View>
  );
};

export default MultiModalDemo;

内容的提问来源于stack exchange,提问作者Quantal

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.24 13:25:09