Nguyễn Đình Cường
0 comment
09 Nov, 2026
Nếu bạn đã viết React cho web, bạn đã có sẵn khoảng một nửa kiến thức để làm ứng dụng di động bằng React Native. Nửa còn lại là những khác biệt về thành phần giao diện, cách tạo kiểu và cách chạy ứng dụng. Bài viết này chỉ ra các điểm đó để bạn đỡ bỡ ngỡ.
Component, props, state, hooks như useState hay useEffect, cách viết JSX và luồng dữ liệu một chiều đều giống hệt. Bạn vẫn chia giao diện thành các component nhỏ, vẫn dùng TypeScript, vẫn gọi API bằng fetch. Nhờ vậy việc học React Native chủ yếu là học thêm thư viện thành phần chứ không phải học lại tư duy.
Trên di động không có div, span hay p. Thay vào đó là các component cốt lõi do React Native cung cấp:
| Web | React Native |
|---|---|
| div | View |
| p, span, h1 | Text |
| img | Image |
| input | TextInput |
| button | Button, Pressable |
| ul, li dài | FlatList |
Quy tắc quan trọng: mọi chữ phải nằm trong thẻ Text. Nếu để chuỗi trần trong View, ứng dụng sẽ báo lỗi.
Không có CSS file hay class. Kiểu được viết bằng đối tượng JavaScript với tên thuộc tính dạng camelCase, và bố cục dựa trên Flexbox. Điểm khác web: chiều mặc định của flex là cột (column) chứ không phải hàng.
import { View, Text, StyleSheet } from 'react-native';
export default function Greeting({ name }: { name: string }) {
return (
<View style={styles.card}>
<Text style={styles.title}>Xin chào, {name}</Text>
<Text style={styles.sub}>Chào mừng bạn quay lại</Text>
</View>
);
}
const styles = StyleSheet.create({
card: {
padding: 16,
borderRadius: 12,
backgroundColor: '#ffffff',
margin: 12,
},
title: { fontSize: 20, fontWeight: '700' },
sub: { marginTop: 4, color: '#666' },
});
Các đơn vị là số không có hậu tố (đơn vị độc lập mật độ điểm ảnh), không có px, rem hay %, trừ khi bạn dùng chuỗi phần trăm cho một số thuộc tính.
Thay vì onClick, hãy dùng Pressable hoặc các thành phần chạm có sẵn với sự kiện onPress. Pressable còn cho phép phản hồi khi nhấn giữ và đổi kiểu khi đang được nhấn.
<Pressable
onPress={() => setCount(count + 1)}
style={({ pressed }) => [styles.btn, pressed && { opacity: 0.6 }]}
>
<Text>Bấm {count}</Text>
</Pressable>
Trang web cuộn tự nhiên, còn trên di động bạn phải khai báo rõ vùng cuộn bằng ScrollView hoặc FlatList. Với danh sách dài hãy dùng FlatList vì nó chỉ vẽ các mục đang hiển thị, tiết kiệm bộ nhớ.
Không có trình duyệt nên không có URL như web. Điều hướng được xử lý bằng thư viện như React Navigation hoặc Expo Router. Nhiều khái niệm web như localStorage, window, document cũng không tồn tại; thay vào đó bạn dùng các thư viện như AsyncStorage hay SecureStore.
Với người mới, Expo là cách khởi đầu nhanh nhất vì không cần cấu hình Android Studio hay Xcode ngay. Bạn có thể quét mã QR để xem ứng dụng trên điện thoại thật. Khi cần mô-đun native tùy biến, bạn vẫn có thể mở rộng sau.
Với nền tảng React, bạn chỉ cần thay bộ thành phần, học cách tạo kiểu mới và làm quen với điều hướng cùng quyền truy cập thiết bị. Hãy bắt đầu bằng một ứng dụng nhỏ rồi mở rộng dần, bạn sẽ thấy quá trình chuyển đổi nhanh hơn dự kiến.
Tin vui là phần lớn mã không phụ thuộc giao diện dùng lại được nguyên vẹn. Hook gọi dữ liệu bạn viết cho web gần như chạy ngay trên di động:
import { useEffect, useState } from 'react';
type Post = { id: number; title: string };
export function usePosts() {
const [data, setData] = useState<Post[]>([]);
const [loading, setLoading] = useState(true);
const [error, setError] = useState<string | null>(null);
useEffect(() => {
let cancelled = false;
fetch('https://jsonplaceholder.typicode.com/posts')
.then((r) => r.json())
.then((json) => { if (!cancelled) setData(json); })
.catch(() => { if (!cancelled) setError('Không tải được dữ liệu'); })
.finally(() => { if (!cancelled) setLoading(false); });
return () => { cancelled = true; };
}, []);
return { data, loading, error };
}
Thư viện quản lý state như Redux Toolkit, Zustand hay TanStack Query cũng dùng được trên di động. Hãy tách riêng phần logic dùng chung thành các hook hoặc module thuần TypeScript, để nếu sau này bạn có cả ứng dụng web và di động, hai bên chia sẻ được phần lớn. Điểm cần cẩn trọng là phụ thuộc vào API trình duyệt như window hay localStorage trong các module dùng chung.
Nếu muốn đi theo một lộ trình có bài tập và dự án thực tế, bạn có thể xem các khóa học tại codebem.com.
Nguyễn Đình Cường
0 comment