Debug React Native 2026: Từ DevTools, Reactotron Đến Sentry — Hướng Dẫn Toàn Diện

Hướng dẫn toàn diện debug React Native 2026: React Native DevTools thay thế Flipper, Reactotron cho state và network, Radon IDE tích hợp editor, Sentry và Firebase Crashlytics cho production. Kèm code ví dụ thực tế và workflow debug chuyên nghiệp.

Tại sao debug là kỹ năng quan trọng nhất mà ít ai dạy bạn

Nếu bạn đã theo dõi các bài trước trong series — về Expo SDK 55, tối ưu hiệu năng, hay quản lý state — thì bạn đã có nền tảng khá vững để xây ứng dụng React Native chất lượng. Nhưng thật lòng mà nói, có một sự thật mà developer nào cũng biết: code luôn có bug. Và khả năng tìm ra bug, hiểu nó, rồi sửa nhanh — đó mới là thứ phân biệt developer giỏi với developer thực sự xuất sắc.

Năm 2026, hệ sinh thái debug React Native đã thay đổi khá nhiều. Flipper chính thức bị deprecate từ React Native 0.73 rồi, và đến RN 0.83 — phiên bản hiện tại — nó đã biến mất hoàn toàn khỏi template mặc định. Thay vào đó, chúng ta có React Native DevTools — công cụ debug chính thức mới, cùng một loạt công cụ bổ trợ mạnh mẽ hơn bao giờ hết.

Vậy nên, bài viết này sẽ đưa bạn qua toàn bộ bộ công cụ debug năm 2026: từ mặc định đến nâng cao, từ development đến production. Mỗi phần đều có code ví dụ thực tế để bạn áp dụng ngay.

React Native DevTools: Công cụ debug mặc định mới

React Native DevTools được ra mắt tại React Universe Conf 2024, và từ React Native 0.76 trở đi, nó đã trở thành công cụ debug mặc định — thay thế hoàn toàn Flipper. Nếu bạn có background web development thì sẽ thấy rất quen, vì nó dùng chung frontend layer với Chrome DevTools.

Cách mở React Native DevTools

Có hai cách chính:

  • Từ Dev Menu: Mở Dev Menu trong app (lắc thiết bị hoặc phím tắt), rồi chọn "Open DevTools"
  • Từ Metro terminal: Nhấn phím j khi Metro bundler đang chạy — cá nhân mình thấy đây là cách nhanh nhất

Phím tắt mở Dev Menu theo từng platform:

  • iOS Simulator: Ctrl + Cmd + Z (hoặc Device → Shake)
  • Android Emulator: Cmd + M (macOS) hoặc Ctrl + M (Windows/Linux)
  • Android thay thế: adb shell input keyevent 82

Các tính năng chính của DevTools

DevTools có nhiều panel quan trọng mà bạn nên nắm vững:

Console Panel — đây là panel bạn sẽ dùng nhiều nhất, thật đấy. Tất cả console.log, console.warn, console.error đều hiển thị ở đây. So với LogBox trong app thì Console panel cho output chính xác và đầy đủ hơn hẳn.

Sources Panel — cho phép duyệt mã nguồn, đặt breakpoint, và step through code từng dòng. Dùng Cmd+P (macOS) hoặc Ctrl+P (Windows/Linux) để tìm file nhanh.

React Components Inspector — giúp xem component tree, kiểm tra props và state của từng component. Công cụ này vô giá khi bạn debug các vấn đề rendering.

React Profiler — đo lường hiệu năng rendering, chỉ ra component nào render quá nhiều lần hoặc quá chậm.

Đặt breakpoint đúng cách

Đây là phần mà khá nhiều developer hay bị vướng. Có hai cách đặt breakpoint:

// Cách 1: Dùng lệnh debugger trực tiếp trong code (KHUYẾN NGHỊ)
const fetchUserData = async (userId: string) => {
  debugger; // App sẽ dừng ở đây khi DevTools đang mở
  const response = await api.get(`/users/${userId}`);
  return response.data;
};

// Cách 2: Click vào số dòng trong Sources panel
// Lưu ý: breakpoint qua UI có thể bị mất sau khi reload app

Mẹo hay: Nếu breakpoint qua giao diện (click số dòng) không hoạt động — chuyện này xảy ra thường xuyên hơn bạn nghĩ — thì cứ dùng debugger; trực tiếp trong code. Đây là cách đáng tin cậy nhất hiện tại.

Xử lý các lỗi phổ biến với DevTools

Dưới đây là những vấn đề hay gặp nhất và cách khắc phục:

Breakpoint hiện "Unbound" (hình tròn xám): Đảm bảo bạn mở DevTools bằng phím j trong Metro terminal hoặc từ Dev Menu. Đừng dùng Chrome DevTools extension — nó không tương thích với React Native đâu.

Không thấy file nguồn trong dự án Expo: Vào DevTools → Settings → Ignore List → Custom exclusion rules, bỏ chọn các quy tắc đang ẩn file. Lỗi này thường xảy ra khi entry point JS nằm trong node_modules/.

Breakpoint nhảy sang dòng khác: Mười phần là vấn đề source map. Thử xóa cache Metro bằng npx expo start --clear rồi reload lại app.

Reactotron: Debug state, network và storage chuyên sâu

Nếu React Native DevTools là "bác sĩ đa khoa" thì Reactotron là "bác sĩ chuyên khoa" — nó không thay thế DevTools mà bổ sung những thứ DevTools chưa làm được. Reactotron là ứng dụng desktop miễn phí, mã nguồn mở, do Infinite Red phát triển — chuyên dùng để inspect state, network request, và local storage.

Khi nào nên dùng Reactotron?

Mình thấy Reactotron đặc biệt hữu ích trong mấy tình huống sau:

  • Debug state management: Xem realtime state changes của Zustand, Redux, MobX-State-Tree
  • Inspect HTTP requests: Xem chi tiết request/response của mọi API call — headers, body, timing đầy đủ
  • Kiểm tra local storage: Xem nội dung AsyncStorage và MMKV mà không cần viết thêm dòng code nào
  • Custom logging: Gửi log có cấu trúc, gọn gàng hơn nhiều so với console.log thông thường

Cài đặt và cấu hình Reactotron với Expo

Đầu tiên, cài dependency:

npx expo install reactotron-react-native

Tiếp theo, tạo file cấu hình ReactotronConfig.ts ở thư mục gốc dự án:

// ReactotronConfig.ts
import Reactotron from "reactotron-react-native";
import AsyncStorage from "@react-native-async-storage/async-storage";

Reactotron.setAsyncStorageHandler!(AsyncStorage)
  .configure({
    name: "MyApp", // Tên hiển thị trên Reactotron desktop
  })
  .useReactNative({
    asyncStorage: true,  // Tự động theo dõi AsyncStorage
    networking: {
      ignoreUrls: /symbolicate/,  // Bỏ qua request hệ thống
    },
    errors: { veto: () => false }, // Theo dõi tất cả errors
    editor: false,
  })
  .connect();

// Thay thế console.log bằng Reactotron.log trong dev
if (__DEV__) {
  console.tron = Reactotron;
}

Rồi import file cấu hình ở đầu entry point:

// app/_layout.tsx (Expo Router) hoặc App.tsx
if (__DEV__) {
  require("../ReactotronConfig");
}

export default function RootLayout() {
  // ...
}

Tích hợp Reactotron với Zustand

Nếu bạn đang dùng Zustand cho state management (như mình đã giới thiệu ở bài trước), bạn có thể kết nối Reactotron để theo dõi mọi thay đổi state. Nói thật là cái này rất tiện:

// plugins/reactotronZustand.ts
import Reactotron from "reactotron-react-native";

export const reactotronZustandPlugin = (storeName: string) => {
  return (config: any) => (set: any, get: any, api: any) => {
    const originalSet = set;
    const newSet: typeof set = (...args: any[]) => {
      originalSet(...args);
      if (__DEV__) {
        Reactotron.display({
          name: storeName,
          preview: "State Updated",
          value: get(),
        });
      }
    };
    return config(newSet, get, api);
  };
};

// Sử dụng trong store
import { create } from "zustand";
import { reactotronZustandPlugin } from "../plugins/reactotronZustand";

export const useCartStore = create<CartState>()(
  reactotronZustandPlugin("CartStore")((set, get) => ({
    items: [],
    addItem: (item) => set((state) => ({
      items: [...state.items, item],
    })),
  }))
);

Mỗi khi state thay đổi, bạn sẽ thấy entry mới trong Reactotron timeline kèm tên store và giá trị mới. Cực kỳ hữu ích khi debug các luồng phức tạp — kiểu bạn biết ngay chính xác action nào gây ra state nào.

Radon IDE: Debug mà không cần rời editor

Radon IDE là extension cho VSCode và Cursor, do Software Mansion phát triển — cùng team đứng sau React Native Reanimated và Gesture Handler. Về cơ bản, nó biến editor của bạn thành IDE đầy đủ cho React Native, tích hợp luôn debug.

Tại sao Radon IDE đáng thử?

Vấn đề lớn nhất với React Native DevTools (theo mình) là phải chuyển tab liên tục giữa editor và cửa sổ debug. Radon IDE giải quyết chuyện này bằng cách đưa tất cả vào trong editor:

  • Device preview ngay trong editor — xem app chạy bên cạnh code
  • Element Inspector: Trỏ vào element trên preview, nó nhảy thẳng đến component trong code
  • Zero-config debugger: Breakpoint hoạt động ngay, không cần cấu hình gì
  • Console logs hiện trong VSCode Output panel
  • Tích hợp sẵn React Query DevToolsRedux DevTools

Cài đặt thì đơn giản lắm — tìm "Radon IDE" trong VSCode Extensions rồi install. Sau đó mở Command Palette (Cmd+Shift+P) và chọn "Radon IDE: Open Panel" là xong.

LogBox và Fast Refresh: Debug nhanh trong lúc phát triển

Không phải lúc nào cũng cần mở DevTools hay Reactotron đâu. Nhiều khi các công cụ nhẹ hơn đã đủ rồi.

LogBox — hệ thống cảnh báo tích hợp

LogBox hiển thị warnings và errors trực tiếp trong app. Khi có lỗi JS nghiêm trọng (syntax error, runtime crash), nó sẽ hiện full-screen error overlay kèm stack trace.

Bạn có thể tùy chỉnh LogBox để ẩn mấy warning không cần thiết:

// App.tsx hoặc _layout.tsx
import { LogBox } from "react-native";

// Ẩn warning cụ thể (dùng regex hoặc string match)
LogBox.ignoreLogs([
  "Warning: componentWillReceiveProps", // Warning từ thư viện cũ
  /Require cycle/,                       // Require cycle warnings
]);

// KHÔNG BAO GIỜ dùng LogBox.ignoreAllLogs() trong production build
// Chỉ nên dùng tạm trong dev khi cần tập trung vào tính năng

Lưu ý: LogBox, Dev Menu, và React Native DevTools đều tự động bị vô hiệu hóa trong production builds. Không cần lo việc remove thủ công.

Fast Refresh — debug UI cực nhanh

Fast Refresh cho phép sửa code và thấy kết quả gần như ngay lập tức mà không mất state hiện tại. Thật sự đây là một trong những cải tiến lớn nhất cho workflow hàng ngày:

  • Sửa JSX/style → UI thay đổi tức thì
  • Sửa logic trong function component → state vẫn giữ nguyên
  • Nếu UI không cập nhật, thử lưu file lần nữa hoặc thêm // @refresh reset ở đầu file
// Thêm comment này ở đầu file để force reset state khi Fast Refresh
// @refresh reset

import { useState } from "react";
import { View, Text } from "react-native";

export default function Counter() {
  const [count, setCount] = useState(0);
  // Mỗi lần lưu file, count sẽ reset về 0
  return (
    <View>
      <Text>Count: {count}</Text>
    </View>
  );
}

Debug native layer: Khi JavaScript không phải thủ phạm

Không phải bug nào cũng nằm ở JavaScript. Đôi khi vấn đề đến từ native code — nhất là khi bạn dùng các thư viện native modules, camera, maps, hay push notifications. Lúc đó phải dùng công cụ native thôi.

Xcode cho iOS

Khi app crash mà JS console không có error gì, hãy mở Xcode lên:

  • Vào Debug → Attach to Process → chọn app đang chạy
  • Mở Console (Cmd+Shift+C) để xem native logs
  • Dùng View Debugging → Capture View Hierarchy để xem layout tree native
  • Kiểm tra Memory Graph Debugger nếu nghi ngờ memory leak

Android Studio và Logcat

Với Android thì Logcat là bạn thân của bạn:

# Xem tất cả log từ React Native app
adb logcat *:S ReactNative:V ReactNativeJS:V

# Lọc chỉ errors
adb logcat *:E

# Lọc theo tên package cụ thể
adb logcat --pid=$(adb shell pidof -s com.yourapp.package)

Android Studio còn có Layout Inspector cho debug UI native và Network Profiler để kiểm tra network traffic ở level hệ điều hành.

Nhận biết crash native vs crash JavaScript

Đây là kỹ năng mà khá nhiều React Native developer bỏ qua, nhưng rất quan trọng:

  • JavaScript crash: App hiện Red Screen (trong dev) hoặc blank screen (production). LogBox hay DevTools console sẽ có error message rõ ràng.
  • Native crash: App đóng đột ngột mà JS console không có gì. Trên Android bạn sẽ thấy "app has stopped", trên iOS thì app biến mất luôn. Lúc này phải check Xcode Console hoặc Logcat.

Debug trong Production: Sentry và Firebase Crashlytics

Tất cả những gì ở trên chỉ giúp bạn debug lúc dev. Nhưng nói thật, bug nguy hiểm nhất lại là bug chỉ xảy ra trên thiết bị thật của người dùng — khi bạn không có DevTools, không có Reactotron, chẳng có gì ngoài crash reports. Đây là lúc cần error tracking tools.

Sentry: Giải pháp toàn diện cho React Native

Sentry là công cụ error tracking phổ biến nhất trong hệ sinh thái React Native năm 2026. Nó theo dõi được cả JavaScript errors lẫn native crashes, kèm context chi tiết giúp bạn reproduce bug dễ hơn rất nhiều.

Cài đặt trong dự án Expo:

# Cài đặt Sentry SDK cho React Native
npx expo install @sentry/react-native

# Chạy wizard để cấu hình tự động
npx @sentry/wizard@latest -i reactNative

Cấu hình cơ bản:

// app/_layout.tsx
import * as Sentry from "@sentry/react-native";

Sentry.init({
  dsn: "https://[email protected]/project-id",

  // Chỉ bật debug trong development
  debug: __DEV__,

  // Performance monitoring
  tracesSampleRate: 1.0,

  // Environment giúp phân biệt dev/staging/production
  environment: __DEV__ ? "development" : "production",

  // Breadcrumbs tự động ghi lại hành động trước khi crash
  enableAutoSessionTracking: true,
  sessionTrackingIntervalMillis: 30000,
});

function RootLayout() {
  return (
    <Sentry.ErrorBoundary fallback={<ErrorFallbackScreen />}>
      {/* App content */}
    </Sentry.ErrorBoundary>
  );
}

export default Sentry.wrap(RootLayout);

Gửi context bổ sung cho Sentry

Crash report mà chỉ có stack trace thôi thì debug hơi khó. Bạn cần thêm context — user info, app state, breadcrumbs tùy chỉnh:

import * as Sentry from "@sentry/react-native";

// Gắn thông tin user khi đăng nhập
const onLoginSuccess = (user: User) => {
  Sentry.setUser({
    id: user.id,
    email: user.email,
    username: user.name,
  });
};

// Thêm breadcrumb cho các action quan trọng
const onCheckout = (cartItems: CartItem[]) => {
  Sentry.addBreadcrumb({
    category: "checkout",
    message: `User started checkout with ${cartItems.length} items`,
    level: "info",
    data: {
      totalItems: cartItems.length,
      totalPrice: cartItems.reduce((sum, item) => sum + item.price, 0),
    },
  });
};

// Bắt error thủ công khi bạn catch nhưng vẫn muốn theo dõi
try {
  await processPayment(orderData);
} catch (error) {
  Sentry.captureException(error, {
    tags: { feature: "payment", provider: "stripe" },
    extra: { orderId: orderData.id },
  });
  showErrorToast("Thanh toán thất bại, vui lòng thử lại");
}

Firebase Crashlytics: Bổ sung cho native crashes

Firebase Crashlytics là công cụ miễn phí của Google, đặc biệt mạnh ở khả năng bắt native crashes — những crash mà Sentry đôi khi bỏ sót. Khuyến nghị của mình: dùng cả hai để coverage tối đa. Nghe thì hơi thừa nhưng tin mình đi, nó xứng đáng.

# Cài đặt Firebase Crashlytics
npx expo install @react-native-firebase/app @react-native-firebase/crashlytics

Thêm plugin vào app.json:

{
  "expo": {
    "plugins": [
      "@react-native-firebase/app",
      "@react-native-firebase/crashlytics"
    ]
  }
}

Sử dụng trong code:

import crashlytics from "@react-native-firebase/crashlytics";

// Ghi log cho crash context
crashlytics().log("User navigated to checkout screen");

// Gắn user info
crashlytics().setUserId("user-123");

// Custom attributes
crashlytics().setAttribute("screen", "Checkout");
crashlytics().setAttribute("cart_items", "5");

// Report non-fatal error
try {
  await submitOrder(orderData);
} catch (error) {
  crashlytics().recordError(error as Error);
}

Source maps: Yếu tố quyết định chất lượng crash reports

Nếu bạn thấy "Minified Code" trong Sentry dashboard thay vì tên file và số dòng thực — thì là bạn chưa upload source maps. Đây là lỗi phổ biến nhất khi cấu hình error tracking, mình từng mất cả buổi chiều vì quên cái này.

Với EAS Build thì may là chỉ cần thêm plugin Sentry vào app.json — source maps sẽ được upload tự động lúc build:

{
  "expo": {
    "plugins": [
      [
        "@sentry/react-native/expo",
        {
          "organization": "your-org",
          "project": "your-project"
        }
      ]
    ]
  }
}

Workflow debug thực tế: Từ phát hiện đến sửa lỗi

Biết công cụ là một chuyện, biết khi nào dùng cái nào mới là kỹ năng quan trọng. Đây là workflow debug mà mình dùng hàng ngày:

Bước 1: Xác định loại bug

  • UI sai (layout, style, animation) → Fast Refresh + DevTools Element Inspector
  • Logic sai (data hiển thị không đúng) → console.log hoặc debugger; + DevTools Sources
  • State không đúng → Reactotron hoặc React Components Inspector
  • API call lỗi → Reactotron Networking panel hoặc DevTools Network
  • App crash → Xem error type (JS hay native), dùng công cụ tương ứng
  • Production crash → Sentry dashboard + Crashlytics

Bước 2: Thu hẹp phạm vi

Nguyên tắc vàng: luôn thu hẹp phạm vi trước khi đào sâu. Đừng đặt breakpoint ở khắp nơi. Hãy hỏi: "Bug ở component nào? Function nào? Dòng nào?" Dùng console.log nhanh để xác định phạm vi trước, rồi mới chuyển sang breakpoint cho chi tiết.

Bước 3: Reproduce có hệ thống

Bug mà không reproduce được thì rất khó sửa. Ghi lại chính xác:

  • Các bước để reproduce
  • Platform (iOS hay Android) và phiên bản OS
  • Trạng thái app trước khi bug xảy ra
  • Network conditions (online/offline, tốc độ mạng)

Bảng so sánh công cụ debug React Native 2026

Bảng tổng hợp để bạn chọn nhanh công cụ phù hợp:

Công cụLoạiDùng khi nàoChi phí
React Native DevToolsMặc địnhDebug JS, breakpoints, component tree, profilingMiễn phí
ReactotronBổ trợState management, API requests, AsyncStorage/MMKVMiễn phí
Radon IDEEditor tích hợpDebug ngay trong VSCode/Cursor, không cần chuyển tabTrả phí
Xcode / Android StudioNativeDebug native crashes, memory leaks, view hierarchyMiễn phí
SentryProductionError tracking, performance monitoring, crash reportsFree tier có sẵn
Firebase CrashlyticsProductionNative crash reports, bổ sung cho SentryMiễn phí

Câu hỏi thường gặp (FAQ)

Flipper có còn dùng được trong React Native 2026 không?

Nói ngắn gọn: không nên. Flipper bị deprecate từ React Native 0.73 và không còn cài mặc định nữa. Trước đây nó gây ra đủ thứ phiền: tăng thời gian build, xung đột dependency cả Android lẫn iOS, và đôi khi còn làm app không start nổi. React Native DevTools là replacement chính thức, được team core khuyến nghị. Nếu dự án cũ còn dùng Flipper, hãy gỡ ra và chuyển sang DevTools + Reactotron.

Làm sao debug app React Native khi không có máy Mac (cho iOS)?

Không có Mac thì vẫn debug được phần JavaScript trên Android emulator bằng DevTools và Reactotron — phần lớn code React Native chạy cross-platform mà. Với iOS, bạn dùng EAS Build để build trên cloud rồi test qua TestFlight trên thiết bị thật. Tuy nhiên, muốn debug native crashes trên iOS thì vẫn cần Xcode, tức là cần Mac hoặc dịch vụ macOS cloud.

Nên dùng Sentry hay Firebase Crashlytics cho production?

Khuyến nghị tốt nhất năm 2026: dùng cả hai. Sentry mạnh về JavaScript error tracking — source maps, breadcrumbs, performance monitoring — bạn sẽ thấy chính xác dòng nào gây lỗi. Crashlytics thì mạnh về native crashes và hoàn toàn miễn phí. Dùng Sentry làm công cụ chính, Crashlytics làm lớp bảo vệ thêm cho native crashes.

Console.log có ảnh hưởng hiệu năng app trong production không?

Có, và nhiều người không biết điều này. LogBox và DevTools tự tắt trong production, nhưng console.log thì vẫn chạy — ảnh hưởng hiệu năng khi log object lớn hoặc gọi liên tục. Cách hay nhất là dùng babel-plugin-transform-remove-console để xóa tự động trong production build. Thêm vào babel.config.js: plugins: [...(__DEV__ ? [] : ['babel-plugin-transform-remove-console'])].

Breakpoint trong React Native DevTools không hoạt động, phải làm sao?

Chuyện này xảy ra hoài luôn. Thứ nhất, mở DevTools đúng cách — nhấn j trong Metro terminal hoặc chọn "Open DevTools" từ Dev Menu. Đừng dùng Chrome DevTools extension vì nó không tương thích. Thứ hai, nếu breakpoint qua UI không ăn, dùng debugger; trong code — cách này tin cậy nhất. Thứ ba, thử npx expo start --clear nếu breakpoint nhảy sai chỗ.

Về Tác Giả Editorial Team

Our team of expert writers and editors.