- React Native khác gì so với ReactJS?
ReactJS là thư viện JavaScript render ra DOM trong browser, output là HTML/CSS. React Native là framework dùng cùng model component + JSX nhưng render ra native UI components (UIView trên iOS, ViewGroup/Android.View trên Android), không có DOM, không có HTML tag. Khác biệt cụ…
- JSX trong React Native khác JSX web ra sao?
Cú pháp JSX giống hệt — {} cho expression, className không tồn tại (RN dùng style), nhưng set tag hợp lệ khác hoàn toàn. Web JSX cho phép mọi HTML element vì cuối cùng compile ra DOM. RN JSX chỉ chấp nhận các component được…
- Vì sao mọi text trong RN phải nằm trong `<Text>`?
Trên iOS và Android, string không phải là một loại view. UIView không biết cách render ký tự — chỉ UILabel/TextView mới làm được. RN buộc bạn bao text trong <Text để binding sang đúng native component. Nếu viết <ViewHello</View, RN throw runtime error: "Text…
- Bridge cũ trong RN là gì? Tại sao 2024+ thay bằng JSI?
Bridge cũ (legacy) là hàng đợi message bất đồng bộ giữa JS thread và Native thread. Mỗi lần JS gọi native (vd setState → re-render UIView), payload được serialize JSON, đẩy qua bridge, deserialize bên kia. Đặc điểm: - Async-only: không thể gọi native sync;…
- Hermes là gì, khác JSC ở đâu?
Hermes là JavaScript engine open-source do Meta viết riêng cho React Native, tối ưu cho thời gian khởi động, bộ nhớ và kích thước app. JSC (JavaScriptCore) là engine của Safari, từng là mặc định của RN. Khác biệt chính: - Biên dịch bytecode trước…
- Component lifecycle trong RN giống/khác React web ra sao?
Giống: RN dùng cùng React core nên hooks (useEffect, useLayoutEffect, useRef...) và class lifecycle (componentDidMount, componentWillUnmount) hoạt động y hệt web. Mount/update/unmount cycle giống. Khác: - Không có DOM event lifecycle (load, DOMContentLoaded). - useLayoutEffect vẫn tồn tại nhưng semantics khác theo architecture: trên Old…
- Props vs State trong RN có khác biệt nào so với React web không?
Hoàn toàn không khác — đây là React core, RN không can thiệp. Props vẫn là dữ liệu cha truyền xuống, immutable từ phía con. State vẫn local, mutable qua setState/useState, trigger re-render khi đổi. Vài điểm cần lưu ý đặc thù RN: - Performance…
- RN render thế nào trên iOS vs Android?
JS code không thay đổi giữa platform, nhưng layer dưới khác hẳn: iOS: mỗi <View map sang một UIView (Objective-C/Swift), <Text → RCTTextView/UILabel, <Image → RCTImageView/UIImageView. Layout dùng Yoga (cross-platform Flexbox engine của Meta), kết quả set frame cho UIView. Android: <View map sang ViewGroup…
- `StyleSheet.create` vs inline style — khác gì, khi nào dùng?
StyleSheet.create({ ... }) validate keys lúc dev (warn nếu sai tên prop, vd colour), freeze object trả về để giữ reference ổn định giữa các render. Lịch sử (RN <0.59) còn thay object bằng integer id để tối ưu bridge — tối ưu này đã…
- Vì sao RN không dùng đơn vị `px` mà dùng "density-independent pixels"?
Số trong style: { width: 100 } không phải physical pixel — đó là DIP (density-independent pixel), tương tự dp Android hay pt iOS. RN tự nhân với PixelRatio.get() để ra physical pixel khi render. Ví dụ trên iPhone 14 (3x density), width: 100 thật…
- `Platform.OS` / `Platform.select` — khi nào dùng, khi nào tách file `.ios.tsx` / `.android.tsx`?
Inline check (Platform.OS / Platform.select) dùng cho khác biệt nhỏ trong cùng một component: Tách file (Component.ios.tsx + Component.android.tsx) dùng khi: - Code khác biệt nhiều (30%) — vd map view dùng react-native-maps iOS gọi Apple Maps, Android gọi Google Maps qua key khác. -…
- Khác biệt cơ bản: RN vs Flutter vs native (Swift/Kotlin) cho dự án mới 2026?
- Khác biệt giữa `View`, `Text`, `Image`, `ScrollView` — mỗi cái dùng khi nào?
<View là container cơ bản — tương đương <div web, không có default text rendering. Dùng cho mọi layout block (row/column). <Text là bắt buộc cho mọi chuỗi ký tự. Hỗ trợ numberOfLines, ellipsizeMode, font style, lồng <Text con để inline format. <Image source={{ uri…
- `FlatList` vs `SectionList` vs `ScrollView` — khi nào chọn cái nào?
ScrollView: render toàn bộ children ngay lập tức. Dùng cho UI ngắn (form, profile screen), không có pattern data-driven. Chậm và tốn memory với list 20 items. FlatList: virtualized list — chỉ render items đang visible + windowSize buffer. Lazy mount và unmount khi scroll…
- `keyExtractor` trong FlatList quan trọng thế nào?
keyExtractor trả về unique string cho mỗi item, để React reconciler biết phân biệt khi data thay đổi (giống key prop trong list React thường). Nếu không cung cấp, FlatList fallback dùng item.key rồi item.id, cuối cùng là index. Dùng index gây bugs nghiêm trọng:…
- `SafeAreaView` built-in vs `react-native-safe-area-context` — vì sao team thường thay built-in?
RN core có <SafeAreaView, hoạt động trên iOS only (đặt padding theo notch/home indicator). Trên Android render như <View thường — không có effect. Bị deprecate-ish và không xử lý đúng khi rotate hay multi-window. react-native-safe-area-context (lib mặc định trong Expo) cung cấp: - Hoạt…
- `KeyboardAvoidingView` — `behavior` chọn `padding` hay `height`?
<KeyboardAvoidingView đẩy nội dung lên khi keyboard mở để không che TextInput. Prop behavior: - padding (recommend cho iOS): thêm padding bottom = chiều cao keyboard. Children giữ nguyên, chỉ vùng dưới được "đẩy" lên. Mượt và predictable. - height: shrink chiều cao container =…
- `TextInput` controlled vs uncontrolled — pattern nào dùng trong RN?
Controlled (chuẩn React, recommend default): state cha giữ value, onChangeText cập nhật. Lợi thế: validate/format on-the-fly, sync với store toàn cục, easy reset. Uncontrolled: dùng defaultValue và onChangeText cache giá trị vào ref ngoài, không bind vào React state. RN không có inputRef.current.value như DOM…
- Image caching trong RN — khi nào dùng `expo-image` / `FastImage`?
<Image core trong RN có cache rất cơ bản: iOS dùng NSURLCache (limit 20MB default), Android dùng OkHttp memory cache. Không có disk cache mạnh, không có placeholder/blur, không có priority queue. Hậu quả: list ảnh lớn → reload từ network khi user scroll lên/xuống…
- `Pressable` vs `TouchableOpacity` / `TouchableHighlight` — RN khuyến nghị 2026?
Pressable (recommend từ RN 0.63+): API hiện đại, một component thay cho cả family Touchable. Function children có signature ({ pressed }) = ReactNode để render khác state, hoặc style function style={({ pressed }) = [...]} để áp style động. Hỗ trợ onLongPress, delayLongPress, hitSlop,…
- `Modal` built-in vs portal-based custom modal — chọn cái nào?
Built-in <Modal: render qua native modal API (UIViewController iOS, Dialog Android). Ưu điểm: tự xử lý back button Android, status bar, true full-screen overlay vượt qua mọi layer. Nhược: animation hạn chế (slide, fade, none), khó style header/backdrop, prop presentationStyle chỉ iOS. Custom modal qua…
- Flexbox trong RN khác CSS web ra sao?
RN tính layout bằng Yoga (engine C++ của Meta). Flexbox chạy gần giống web nhưng giá trị mặc định khác — đây là chỗ dev web hay vấp: React Native Web CSS --------- flexDirection column row flexShrink 0 1 alignContent flex-start stretch flex chỉ nhận…
- `react-navigation` v7 — Stack / Tab / Drawer khi nào dùng?
Stack Navigator: điều hướng kiểu push/pop — màn hình mới đè lên màn cũ. Có hai bản: @react-navigation/native-stack dùng UINavigationController (iOS) và Fragment (Android) nên animation, gesture do platform xử lý — nên chọn mặc định; @react-navigation/stack viết bằng JS, tuỳ biến animation được nhiều…
- Native stack (`@react-navigation/native-stack`) vs JS stack — khác biệt hiệu năng?
JS stack (@react-navigation/stack): toàn bộ animation và transition viết bằng JS qua Reanimated. Linh hoạt: custom transition, modal effect, gesture-driven dismiss. Nhược: animation chạy JS thread → có thể jank nếu thread busy lúc transition. Native stack (@react-navigation/native-stack): wrap react-native-screens — dùng UINavigationController (iOS) và…
- Deep linking config trong RN — setup ra sao?
Deep link cho phép URL bên ngoài (web link, push notification) mở thẳng vào một screen cụ thể trong app. Bước 1 — Khai báo URL scheme: - iOS: Info.plist thêm CFBundleURLTypes với scheme custom (myapp://). - Android: AndroidManifest.xml thêm <intent-filter cho android.intent.action.VIEW + <data…
- `useNavigation` / `useRoute` — typing với TypeScript ra sao?
react-navigation v7 cung cấp generic types để type-safe navigation prop và route params. Khai báo param list: Trong screen component: Tip 2026: declare global type-safe navigation bằng module augmentation: Khi đó useNavigation() không cần generic — TypeScript tự suy luận.
- Truyền params giữa screens — những lỗi hay gặp?
navigation.navigate('Detail', { product }) truyền params qua route. Vài lỗi hay gặp: 1. Object reference vs value: params được serialize ngầm (clone) nội bộ navigation state. Truyền object lớn (nested deep, function, Date) trigger warning "Non-serializable values were found in the navigation state". Hậu quả:…
- Authentication navigation pattern — split stacks là gì?
- AsyncStorage vs MMKV vs SecureStore — chọn theo nhu cầu nào?
@react-native-async-storage/async-storage: key-value persistent, async API, dữ liệu lưu file (iOS) hoặc SQLite (Android). Cross-platform, ổn định, hệ sinh thái lớn. Nhược: async (Promise mỗi call) → block render khi data nhiều, plain text không mã hoá, limit ~6MB Android. react-native-mmkv: key-value nhanh, đồng bộ API,…
- Redux Toolkit vs Zustand vs Jotai trong RN 2026 — chọn cái nào?
Redux Toolkit (RTK): full-featured. RTK Query thay axios cho server state, devtools tốt nhất, time-travel debugging. Phù hợp app lớn (10+ engineers), cần audit trail rõ ràng. Boilerplate vẫn nặng dù RTK đã giảm so với Redux cổ điển. Trên RN, devtools cần Reactotron hoặc…
- TanStack Query trong RN — cấu hình persister thế nào?
React Query lưu cache trong memory; reload app là mất. Persister cho phép serialize cache vào storage để hydrate khi mở lại app, UI hiển thị data ngay không chờ network. Setup với MMKV (recommend RN): Lưu ý: - focusManager cần custom event vì RN…
- Context API trong RN — lỗi re-render cụ thể là gì?
Context không có shallow compare — bất kỳ consumer nào cũng re-render khi value object đổi reference, kể cả khi field mà consumer đó đọc không đổi. Anti-pattern phổ biến: Vấn đề: child chỉ cần theme cũng re-render khi user đổi. Cách fix: 1. Tách…
- Form library trong RN — vì sao react-hook-form thường được chọn?
Form lớn (5+ inputs) trong RN thường gặp 2 vấn đề: 1. Controlled state ở cha → mỗi keystroke re-render toàn form, lag visible trên Android low-end. 2. Validation phức tạp (cross-field, async) viết tay rất rối. react-hook-form giải quyết: - State giữ trong ref…
- Networking trong RN — fetch vs axios, retry, offline detection ra sao?
fetch: built-in, đủ dùng cho 80% case. Yếu điểm: không timeout default (phải dùng AbortController), không retry, parse JSON cần .json() rời. axios: API gọn hơn, transformer built-in, interceptor cho auth header và refresh token, timeout config dễ. Retry / backoff: dùng axios-retry hoặc viết…
- Vì sao FlatList với 10k items vẫn mượt? Tinh chỉnh `windowSize`/`maxToRenderPerBatch`/`getItemLayout` ra sao?
FlatList virtualize: chỉ mount items hiện đang trong "window" (vùng nhìn thấy + buffer hai phía), unmount items ngoài window khi scroll. Memory ổn định không phụ thuộc tổng số item. Tham số quan trọng: - windowSize (default 21): số "screenful" được render. 21 nghĩa…
- `useCallback` / `useMemo` trong RN — khi nào thực sự cần?
Quy tắc giống React web: memo hoá chỉ có ích khi cần giữ reference ổn định cho thứ đang so sánh reference (React.memo, dependency array, props của FlatList). Khác biệt là trên máy Android cấu hình thấp, render thừa trong list dài dễ thành giật…
- Hermes engine — bật bằng cách nào, đo improvement ra sao?
Hermes là default từ RN 0.70 (Android) và 0.71 (iOS). Dự án mới Expo SDK 50+ và bare CLI đều bật sẵn. Bật/tắt Hermes: - Expo: app.json → "jsEngine": "hermes" (hoặc "jsc"). Build qua EAS. - Bare: - android/gradle.properties → hermesEnabled=true. - ios/Podfile → :hermesenabled…
- `removeClippedSubviews` — đo trade-off thế nào?
- `InteractionManager.runAfterInteractions` — use case là gì?
InteractionManager là API trong RN cho phép defer task nặng cho đến khi animation/transition hoàn thành. Mục đích: tránh block animation, giữ FPS smooth lúc transition. Từ RN 0.80 API này đã bị đánh dấu deprecated; docs khuyên dùng requestIdleCallback thay thế. Use case điển…
- Image-related perf bugs — thumbnails, blur placeholder, prefetch xử lý ra sao?
List nhiều ảnh thường gặp: 1. Layout shift do ảnh chưa load: ảnh remote không có intrinsic size → khi load xong, item thay đổi chiều cao → list jump. Fix: set width/height cứng hoặc aspectRatio. 2. White flash trước khi ảnh load: dùng placeholder.…
- `react-native-screens` `enableScreens(true)` — tác dụng gì?
Mặc định trong RN cũ, mỗi screen của react-navigation render thành một <View trong cùng cây React. Tất cả screen trong stack đều mount → giữ nguyên React tree → tốn memory và chậm dần khi navigate sâu. enableScreens() (default true từ react-navigation v6+) bật…
- Profiling RN — RN DevTools, Systrace, Xcode Instruments dùng khi nào?
- New Architecture là gì, gồm những gì, mặc định từ RN version nào?
New Architecture là tên gọi chung cho 3 phần Meta viết lại RN từ năm 2020: 1. JSI (JavaScript Interface): C++ layer thay Bridge cũ. JS engine có tham chiếu trực tiếp tới object C++/native — gọi sync, không serialize JSON. 2. TurboModules: thay native…
- JSI là gì, khác Bridge cũ thế nào về cơ chế gọi native?
- Fabric — renderer mới hoạt động ra sao, khác UIManager cũ điểm nào?
- TurboModules vs NativeModules cũ — khác biệt cụ thể?
- Codegen — vì sao bắt buộc trong New Architecture?
- Bridgeless mode là gì?
- Migrate library cũ sang New Architecture — checklist gì?
- Hermes + New Arch — vì sao là combo mặc định 2026?
- Khi nào cần viết Native Module thay vì tìm package có sẵn?
Quy tắc: luôn ưu tiên npm package trước. Lý do: lib có sẵn được test trên nhiều device, có CI cross-platform, được community fix bug. Tự viết = bạn own toàn bộ maintenance. Khi cần viết native module: 1. Feature platform mới chưa có lib:…
- Viết Native Module Android (Kotlin) — hello world step-by-step?
- Viết Native Module iOS (Swift) — hello world step-by-step?
- TurboModule spec file (`.ts`) → Codegen flow chi tiết?
- Expo Modules API — khác biệt với TurboModule và khi nào dùng?
Expo Modules API là layer abstraction cao hơn TurboModule do Expo team viết. Cùng mục đích (gọi native từ JS) nhưng API gọn hơn nhiều, đặc biệt khi viết Swift/Kotlin idiomatic. TurboModule (RN core): - Spec TypeScript bắt buộc. - Native code phải kế thừa…
- Animated API và Reanimated — chọn cái nào?
Animated API (built-in RN core): - Driver useNativeDriver: true đẩy animation lên native thread, smooth. - Hạn chế: native driver chỉ animate được thuộc tính không ảnh hưởng layout (opacity, transform); animate width/height/top phải useNativeDriver: false → chạy trên JS thread, dễ jank. - API…
- `useSharedValue` / `useAnimatedStyle` — chạy trên UI thread thế nào?
- `react-native-gesture-handler` — vì sao thay `PanResponder`?
PanResponder (built-in): - Mỗi gesture event đi qua bridge → JS xử lý → có lag. - Không support gesture native (long-press riêng cho iOS, fling Android). - Conflict với ScrollView/Modal hay xảy ra (event không propagate đúng). react-native-gesture-handler (RNGH): - Gesture detect và state…
- `LayoutAnimation` — khi nào đủ dùng?
LayoutAnimation là built-in API — khai báo "tôi muốn next layout change được animate", và RN tự interpolate giữa layout cũ và mới. Use case phù hợp: - Add/remove item trong list ngắn (FlatList animation chuyển vị trí). - Expand/collapse accordion. - Show/hide UI block…
- RN-Skia — use case (canvas, charts, blur, glassmorphism)?
- Expo managed vs bare workflow vs vanilla CLI — quyết định 2026?
Expo managed (npx create-expo-app): - Xcode/Android Studio không cần cài (build qua EAS Cloud). - Native config qua app.json + Expo plugins, không động ios//android/ folder. - Hot reload và OTA update mặc định. - Hạn chế: chỉ dùng module trong Expo SDK + module…
- Metro bundler — khác Webpack ra sao?
Metro là bundler default của RN, do Meta viết. Tối ưu cho dev experience mobile (hot reload nhanh, source map cho native). Khác Webpack: Metro Webpack --------- Target RN bundle (JS+assets cho mobile) Web bundle (JS+CSS+HTML) Entry Một entry duy nhất Multi-entry chunking Transform Babel…
- EAS Build vs build local — trade-off?
Build local: - iOS: cần macOS + Xcode license. - Android: cần JDK + Android Studio + SDK. - Build time: 5–15 phút mỗi lần. - Code signing: tự manage cert/profile (iOS) và keystore (Android). - Pros: zero cost, debug build nhanh hơn (cache local),…
- OTA updates — Expo Updates / EAS Update / CodePush — option nào 2026?
OTA (Over-The-Air) update cho phép push JS bundle mới mà không cần build/upload App Store/Play Store. User mở app → background fetch bundle → hot-swap. Microsoft CodePush (legacy): - Tool đầu tiên phổ biến (~2015). - Deprecated: Microsoft thông báo retire CodePush tháng 3/2025. Migrate…
- App size optimization — ProGuard/R8, Hermes, ABI splits, asset compression?
- Jest + React Native Testing Library — viết unit test cho component thế nào?
@testing-library/react-native (RNTL) cung cấp API tương tự @testing-library/react (web) nhưng adapt cho RN component tree. Setup: jest.config.js: Test ví dụ: Best practices: - Query bằng accessibility role/label (getByRole, getByLabelText) thay vì testID — tăng coverage a11y luôn. - Mock native module qua jest.mock('react-native-mmkv', () =…
- Detox vs Maestro — chọn cho E2E?
Detox (Wix): - E2E test framework cho RN/iOS/Android, viết bằng JS/TS. - Cài đặt phức tạp: cần custom build (detox-cli), config simulator/emulator, sync với JS thread qua RN. - Mạnh: tích hợp sâu RN (sync với animations, async ops), assertion mạnh. - Yếu: setup khó,…
- React Native DevTools (RN 0.76+) — thay Flipper ra sao?
Flipper là tool debug cũ do Meta xây cho RN — desktop app có console, network inspector, layout inspector, plugin ecosystem (database, AsyncStorage). Deprecated từ RN 0.74+ vì: - Khó maintain cross-platform (Java/Obj-C bridge). - Chậm và crash thường xuyên trên Apple Silicon. - Plugin…
- Snapshot testing trong RN — khi nào hữu ích, khi nào hại?
Snapshot test = render component, serialize tree thành text/JSON, lưu file .snap. Chạy lại sau, so với snapshot cũ. Khác → fail. Hữu ích khi: - Component thuần presentation (Avatar, Badge, Tag) — UI ít đổi, snapshot bắt regression vô tình. - Lib component public…
- Permissions trong RN — `react-native-permissions` cross-platform pattern?
react-native-permissions là lib chuẩn cho iOS/Android permission. API thống nhất: Setup config: - iOS: Info.plist thêm key NSCameraUsageDescription, NSLocationWhenInUseUsageDescription, ... với mô tả lý do (App Store reject nếu thiếu hoặc generic). - Android: AndroidManifest.xml thêm <uses-permission. Android 6+ cần runtime request, lib tự handle.…
- Accessibility trong RN — `accessibilityLabel`, `accessibilityRole`, screen reader thế nào?
RN expose accessibility props từ iOS VoiceOver và Android TalkBack để screen reader mô tả UI cho user khiếm thị. Props chính: - accessible={true}: bật accessibility cho component (mặc định false cho View, true cho Text/Button). - accessibilityLabel: text screen reader đọc. Override children text…
- i18n trong RN — `react-i18next` / `i18n-js`, RTL support?
Nên chọn library nào: - react-i18next: mạnh nhất, ecosystem React lớn. Hỗ trợ namespace, plural, interpolation, lazy load translation file. - i18n-js (cũ, FormatJS-style): nhẹ hơn, ít feature, vẫn dùng nhiều legacy. - expo-localization: detect locale từ device, dùng kèm react-i18next. Setup react-i18next: Component: RTL…
- Push notifications — FCM + APNs, Expo Notifications, setup ra sao?
Hai dịch vụ native cần biết: - APNs (Apple Push Notification service): iOS push. - FCM (Firebase Cloud Messaging): Android push, có thể proxy iOS qua APNs. Option 1 — Direct (@react-native-firebase/messaging + APNs): - Setup phức tạp: cần Firebase project, push cert/auth key APNs,…
- Security trong RN — Keychain/Keystore, certificate pinning, encrypted storage?