Modal là component hiển thị nội dung đè lên giao diện chính (overlay). Dùng cho dialog, bottom sheet, form nhập liệu, xác nhận hành động quan trọng.
Import
import { Modal, View, Text, Button, StyleSheet } from 'react-native';
Cú pháp cơ bản
<Modal
animationType="slide" // 'slide' | 'fade' | 'none'
transparent={true} // true: nền trong suốt, false: nền trắng
visible={isVisible} // boolean: hiển thị/ẩn
onRequestClose={() => {}} // Android: bắt buộc khi transparent=true
onShow={() => {}} // Callback khi hiện
onDismiss={() => {}} // Callback khi tắt
presentationStyle="pageSheet" // iOS: 'fullScreen' | 'pageSheet' | 'formSheet' | 'overFullScreen'
>
Nội dung Modal
</Modal>
Các props quan trọng
| Prop | Kiểu | Mô tả |
|---|---|---|
visible | boolean | Kiểm soát hiển thị/ẩn. Bắt buộc. |
animationType | enum | slide (từ dưới), fade (mờ dần), none. |
transparent | boolean | true: cho phép nền trong suốt, tùy biến UI hoàn toàn. |
presentationStyle | enum (iOS) | Kiểu hiển thị: fullScreen, pageSheet (mặc định), formSheet (nhỏ giữa), overFullScreen. |
onRequestClose | func | **Bắt buộc** trên Android khi transparent={true}. Gọi khi bấm back button. |
onShow / onDismiss | func | Callback khi modal hiện/biến mất (sau animation). |
supportedOrientations | array | iOS: giới hạn xoay màn hình khi modal mở. |
Ví dụ cơ bản: Modal slide từ dưới
import React, { useState } from 'react';
import { Modal, Button, View, Text, StyleSheet } from 'react-native';
const App = () => {
const [isVisible, setModalVisible] = useState(false);
return (
setModalVisible(false)}
>
Modal Window Testing!
);
};
const styles = StyleSheet.create({
centeredView: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
marginTop: 22,
},
modalView: {
width: 300,
height: 200,
margin: 20,
backgroundColor: 'white',
borderRadius: 20,
padding: 35,
alignItems: 'center',
shadowColor: '#000',
shadowOffset: { width: 0, height: 2 },
shadowOpacity: 0.25,
shadowRadius: 4,
elevation: 5,
},
modalText: { marginBottom: 15, textAlign: 'center', fontSize: 18 },
modalButton: { marginTop: 15 },
});
export default App;
Ví dụ nâng cao: Bottom Sheet (trượt từ dưới lên)
import React, { useState, useRef } from 'react';
import { Modal, View, Text, StyleSheet, TouchableOpacity, Animated } from 'react-native';
const BottomSheet = ({ visible, onClose, children }) => {
const translateY = useRef(new Animated.Value(0)).current;
React.useEffect(() => {
Animated.timing(translateY, {
toValue: visible ? 0 : 1,
duration: 300,
useNativeDriver: true,
}).start();
}, [visible, translateY]);
const animatedStyle = {
transform: [{ translateY: translateY.interpolate({
inputRange: [0, 1],
outputRange: ['0%', '100%'],
})}],
};
if (!visible) return null;
return (
{children}
);
};
const styles = StyleSheet.create({
overlay: { flex: 1, backgroundColor: 'rgba(0,0,0,0.5)' },
sheet: {
position: 'absolute',
bottom: 0,
left: 0,
right: 0,
backgroundColor: 'white',
borderTopLeftRadius: 20,
borderTopRightRadius: 20,
padding: 20,
maxHeight: '80%',
},
});
// Sử dụng
const App = () => {
const [show, setShow] = useState(false);
return (
);
};
Best Practices
- Luôn dùng
useStateđiều khiểnvisible. - Trên Android,
onRequestClose**bắt buộc** khitransparent={true}. - Dùng
KeyboardAvoidingViewbên trong Modal nếu có input text. - Cho UI phức tạp, cân nhắc
react-native-modal,react-navigation(modal screen), hoặc@gorhom/bottom-sheet.