如何将Modal组件逻辑内聚并向父组件暴露交互能力
实现Modal组件的状态内聚与「Tell, Don't Ask」原则应用
要把Modal的显隐逻辑完全内聚到组件内部,同时遵循「Tell, Don't Ask」原则(父组件只下达指令,不传递状态/修改函数),可以通过**React的forwardRef + useImperativeHandle**实现,让Modal自己管理状态,对外暴露操作方法。
第一步:重构TransferPassportModal组件
把显隐状态移到组件内部,对外暴露open和close方法:
import { forwardRef, useState, useImperativeHandle } from 'react'; import { Modal, View, TouchableOpacity } from 'react-native'; import Icons from '你的Icons组件路径'; // 替换成实际路径 const TransferPassportModal = forwardRef(({ passport_id }, ref) => { const [visible, setVisible] = useState(false); const [input_text, setInputText] = useState(''); const [loading, setLoading] = useState(false); // 对外暴露的操作方法 useImperativeHandle(ref, () => ({ open: () => setVisible(true), close: () => setVisible(false) })); const closeModal = () => { setVisible(false); // 可选:关闭时重置输入框等临时状态 setInputText(''); }; return ( <Modal animationType="fade" transparent={true} visible={visible}> <View style={styles.modal}> <View style={styles.modal_content}> <TouchableOpacity onPress={closeModal} style={styles.close_modal_button}> <Icons name="close" size={20} /> </TouchableOpacity> {/* 剩余表单代码 */} </View> </View> </Modal> ); }); // 保留原有样式定义 const styles = { // 你的样式代码 }; export default TransferPassportModal;
第二步:修改Passport父组件
父组件不再管理Modal的显隐状态,而是通过Ref调用Modal暴露的方法:
import { useRef } from 'react'; import { View, Text, TouchableOpacity } from 'react-native'; import TransferPassportModal from './TransferPassportModal'; // 替换成实际路径 const Passport = ({ passport }) => { // 创建Ref获取Modal实例 const transferModalRef = useRef(null); const openTransferModal = () => { // 直接向Modal下达"打开"指令 transferModalRef.current.open(); }; return ( <View style={styles.wrapper}> <View style={styles.infos_wrapper}> <Text style={styles.name}>{passport.nome}</Text> <Text style={styles.text}>{passport.codigo}</Text> </View> <View style={styles.buttons_wrapper}> {/* 打开Modal的触发按钮 */} <TouchableOpacity onPress={openTransferModal}> <Text>打开转移护照弹窗</Text> </TouchableOpacity> {/* 渲染Modal,传递Ref和passport_id */} <TransferPassportModal ref={transferModalRef} passport_id={passport.ingresso} /> </View> </View> ); }; // 保留原有样式定义 const styles = { // 你的样式代码 }; export default Passport;
为什么这符合「Tell, Don't Ask」原则?
- 父组件不再询问Modal的状态,也不传递状态修改逻辑,而是直接告诉Modal执行“打开”或“关闭”的动作。
- Modal完全掌控自己的内部状态,所有和显隐相关的逻辑都封装在组件内部,外部只需要调用暴露的方法即可,实现了逻辑内聚。
内容的提问来源于stack exchange,提问作者Bernardo Benini Fantin
相关产品推荐
相关产品推荐

