React Native自定义Modal需二次点击才显示问题求助
解决React Native自定义Modal二次点击才生效的问题
问题原因
你封装的CustomModal同时维护了内部状态isVisible和外部传入的modalVisible,但关闭Modal时仅更新了内部状态,未同步更新外部状态,导致外部的visible与内部isVisible状态不一致:
- 首次点击bell图标,外部
visible变为true,内部isVisible同步为true,Modal正常打开; - 点击关闭按钮后,内部
isVisible变为false,但外部visible仍为true; - 此时再次点击bell,会先将
visible改为false,触发useEffect同步内部isVisible为false(无实际变化),Modal无响应; - 第三次点击才会将
visible改为true,同步内部状态后Modal才会打开,这就是需要两次点击的核心原因。
解决方案
方案一:移除内部状态,完全依赖外部控制(推荐)
直接使用外部传入的modalVisible控制Modal显示,新增onClose回调通知外部更新状态,避免状态不一致:
修改后的CustomModal组件:
import { View, Text, TouchableOpacity } from 'react-native'; import Icon from 'react-native-vector-icons/MaterialCommunityIcons'; import React from 'react'; import Modal from 'react-native-modal'; export default function CustomModal({ modalVisible, onClose, children }) { return ( <Modal isVisible={modalVisible} onSwipeComplete={onClose} style={{ justifyContent: 'flex-end', margin: 0, alignItems: 'center' }} useNativeDriver={true} backdropTransitionOutTiming={0} hideModalContentWhileAnimating onBackButtonPress={onClose} onBackdropPress={onClose}> <View style={{ backgroundColor: 'white', padding: 0, height: 'auto', borderTopRightRadius: 12, borderTopLeftRadius: 12, width: '100%', }}> <View style={{ backgroundColor: '#f5f6f6', justifyContent: 'space-between', flexDirection: 'row', alignItems: 'center', padding: 16, borderTopRightRadius: 12, borderTopLeftRadius: 12, }}> <Text style={{ color: 'black', fontSize: 16 }}>Hello</Text> <TouchableOpacity onPress={onClose}> <Icon color="black" name="close" size={16} /> </TouchableOpacity> </View> {/* 注意:原代码重复渲染了两次children,这里保留一处即可 */} <View style={{ padding: 20, alignItems: 'center' }}>{children}</View> </View> </Modal> ); }
调用处代码修改:
const [visible , setVisible] = useState(false); <CustomModal modalVisible={visible} onClose={() => setVisible(false)} /> <IconButton icon='bell' iconColor='#EA580C' size={30} onPress={() => setVisible(prev => !prev)} />
方案二:保留内部状态,同步更新外部状态
如果需要保留内部状态,在关闭Modal时调用外部回调同步状态:
修改CustomModal的closeModal函数:
export default function CustomModal({ modalVisible, onClose, children }) { const [isVisible, setIsVisible] = useState(modalVisible); useEffect(() => { setIsVisible(modalVisible); }, [modalVisible]); const closeModal = () => { setIsVisible(false); onClose?.(); // 通知外部更新状态 }; // 其余组件代码不变 }
调用处同样传入onClose={() => setVisible(false)}即可。
内容的提问来源于stack exchange,提问作者Coder Duck
相关产品推荐
相关产品推荐

