راهنمای مهاجرت به معماری جدید React Native در ۲۰۲۶: از Bridge تا JSI، TurboModules و Fabric

سال ۲۰۲۶ مهاجرت به معماری جدید React Native اجباری شده. این راهنما فرآیند مهاجرت از Bridge به JSI، TurboModules و Fabric رو گام‌به‌گام با نمونه کد واقعی آموزش می‌ده. شامل چالش‌های رایج، زمان‌بندی و ابزارهای مفید.

مقدمه

خب، سال ۲۰۲۶ رسید و React Native یه نقطه عطف جدی رو رد کرد. با انتشار نسخه ۰.۸۲، معماری قدیمی به طور کامل غیرفعال شده و معماری جدید (New Architecture) — شامل JSI، TurboModules، Fabric و Codegen — تنها گزینه موجوده. اگر هنوز اپلیکیشن شما از Bridge قدیمی استفاده می‌کنه، الان زمان مهاجرته. نه فردا، نه هفته بعد، الان.

نتایج تیم‌هایی که زودتر دست به کار شدن واقعاً چشمگیره: کاهش ۴۳ درصدی زمان راه‌اندازی سرد (Cold Start)، افزایش ۳۹ درصدی سرعت رندرینگ و کاهش ۲۰ تا ۳۰ درصدی مصرف حافظه. شرکت‌هایی مثل Shopify با موفقیت اپلیکیشن‌های بزرگ خود — با صدها صفحه و ماژول نیتیو — رو مهاجرت دادن و همچنان انتشار هفتگی‌شون رو حفظ کردن. صادقانه بگم، وقتی خودم اولین بار این آمارها رو دیدم فکر کردم اغراق‌آمیزه، ولی بعد از اینکه مهاجرت رو روی یکی از پروژه‌هام انجام دادم، تفاوت رو با چشم خودم دیدم.

در این راهنما، اول مشکلات معماری قدیمی رو بررسی می‌کنیم، بعد چهار ستون اصلی معماری جدید رو عمیق توضیح می‌دیم و در نهایت یک فرآیند مهاجرت گام‌به‌گام با نمونه کدهای واقعی ارائه می‌کنیم.

چرا معماری قدیمی دیگر کافی نیست؟

برای اینکه بفهمید چرا مهاجرت اینقدر مهمه، باید اول ببینید معماری قدیمی چه مشکلاتی داشت.

در معماری قدیمی React Native، لایه جاوااسکریپت و لایه نیتیو در دو دنیای کاملاً جدا زندگی می‌کردند. هر بار که نیاز به ارتباط بود، داده‌ها باید از یک «پل» (Bridge) عبور می‌کردند — لایه‌ای که همه چیز رو به رشته‌های JSON تبدیل (serialize) و در طرف دیگر تجزیه (deserialize) می‌کرد. اگر تا حالا با یه اپلیکیشن سنگین با انیمیشن‌های زیاد کار کرده باشید، احتمالاً اون لگ‌های عجیب و غریب رو تجربه کردید.

مشکلات اصلی Bridge

  • ارتباط غیرهمزمان اجباری: تمام ارتباطات بین جاوااسکریپت و نیتیو غیرهمزمان بود. حتی برای یه کار ساده مثل خواندن یک مقدار از حافظه محلی، باید منتظر پاسخ Promise می‌موندید. این برای خیلی از سناریوها واقعاً آزاردهنده بود.
  • سربار سریال‌سازی JSON: هر پیام باید به JSON تبدیل، در صف قرار داده و در طرف دیگر تجزیه می‌شد. در اپلیکیشن‌های شلوغ با انیمیشن‌ها و فراخوانی‌های API متعدد، این صف طولانی شده و تأخیر ایجاد می‌کرد.
  • بارگذاری همه ماژول‌ها در شروع: تمام ماژول‌های نیتیو هنگام راه‌اندازی اپلیکیشن مقداردهی اولیه می‌شدند — حتی اگر هرگز استفاده نمی‌شدند! اپلیکیشنی با ۵۰ ماژول نیتیو، همه ۵۰ تا رو در شروع بارگذاری می‌کرد. فکرش رو بکنید.
  • دو کپی از درخت DOM: معماری قدیمی باید دو نسخه از درخت نودها و DOM رو نگهداری می‌کرد که مصرف حافظه رو بالا می‌برد.
  • عدم امکان اولویت‌بندی: هیچ راهی برای قطع کردن تسک‌های کم‌اولویت و اولویت دادن به آپدیت‌های فوری وجود نداشت.

یه تشبیه ساده: Bridge قدیمی مثل ارسال نامه بود — هر پیام باید نوشته، در پاکت گذاشته، ارسال و در مقصد باز می‌شد. معماری جدید مثل برداشتن تلفنه — ارتباط مستقیم و آنی. از تجربه خودم می‌گم، وقتی اولین بار بعد از مهاجرت اپلیکیشن رو اجرا کردم، فرق سرعت باز شدن واقعاً محسوس بود.

چهار ستون اصلی معماری جدید

معماری جدید React Native از چهار مؤلفه اصلی تشکیل شده. بیاید هر کدوم رو جداگانه بررسی کنیم.

۱. JSI (JavaScript Interface)

JSI یک API سبک‌وزن مبتنی بر C++ است که جایگزین Bridge قدیمی شده. ایده‌اش ساده ولی قدرتمنده: جاوااسکریپت می‌تونه مستقیماً به اشیاء C++ ارجاع بده و بالعکس. دیگه خبری از سریال‌سازی داده‌ها به JSON نیست — فراخوانی مستقیم توابع.

تفاوت‌های کلیدی JSI با Bridge:

ویژگیBridge قدیمیJSI جدید
نوع ارتباطغیرهمزمانهمزمان و غیرهمزمان
انتقال دادهسریال‌سازی JSONارجاع مستقیم C++
بارگذاری ماژول‌هاهمه در شروعتنبل / در صورت نیاز
پشتیبانی موتور JSفقط JavaScriptCoreHermes، V8، JSC
عملکردکندتر (مبتنی بر صف)سریع‌تر (فراخوانی مستقیم)
حافظهدو کپی DOMحافظه مشترک

با JSI، زمان پاسخ‌گویی از میلی‌ثانیه به میکروثانیه کاهش پیدا می‌کنه. اشیاء بزرگ بدون کپی بین جاوااسکریپت و نیتیو به اشتراک گذاشته می‌شن و ارتباط بلادرنگ برای کاربردهایی مثل پردازش صوت و بینایی کامپیوتری ممکن می‌شه. این تفاوت رو وقتی با یه اپلیکیشن سنگین کار می‌کنید حس خواهید کرد.

۲. TurboModules

TurboModules جایگزین Native Modules قدیمی شدن و از JSI برای ارتباط مستقیم با کد نیتیو استفاده می‌کنن. مهم‌ترین تفاوتشون بارگذاری تنبل (Lazy Loading) هست.

بذارید با یه مثال توضیح بدم. فرض کنید اپلیکیشن شما ۵۰ ماژول نیتیو داره اما فقط ۵ تا در اولین تعامل کاربر مورد نیازه. TurboModules بارگذاری ۴۵ ماژول دیگه رو تا زمانی که واقعاً لازم بشن به تعویق می‌اندازه. نتیجه؟ زمان راه‌اندازی به شدت کاهش پیدا می‌کنه.

نکته مهم دیگه اینکه TurboModules می‌تونن متدهای همزمان (synchronous) داشته باشن که مقادیر رو بلافاصله برمی‌گردونن — بدون نیاز به Promise. این قابلیت خیلی جاها به دردتون می‌خوره.

۳. Fabric (موتور رندرینگ جدید)

Fabric یک بازنویسی کامل لایه رندرینگ UI هست که جایگزین UIManager/ViewManager قدیمی شده. Fabric منطق رندرینگ رو با استفاده از یک هسته مشترک C++ در تمام پلتفرم‌ها یکپارچه می‌کنه.

ویژگی‌های کلیدی Fabric:

  • محاسبه لایه‌بندی همزمان: Fabric می‌تونه layout رو به صورت همزمان محاسبه کنه — این برای انیمیشن‌ها و پاسخ‌های لمسی حیاتیه.
  • رندرینگ همزمان (Concurrent Rendering): پشتیبانی از ویژگی‌های React 18+ مثل Suspense و Transitions.
  • درخت سایه تغییرناپذیر (Immutable Shadow Tree): هر آپدیت UI یک نسخه جدید از درخت سایه C++ ایجاد می‌کنه. این تضمین می‌کنه که چندین رندر «در حال انجام» بتونن بدون تداخل با هم وجود داشته باشن.
  • Props با ایمنی نوع: تعریف props با type-safety از طریق Codegen.

نتیجه عملی چیه؟ یکپارچگی UI بین iOS و Android بهتر می‌شه، انیمیشن‌ها روان‌تر اجرا می‌شن، پاسخ لمسی آنی احساس می‌شه و اسکرول لیست‌های پیچیده دیگه لگ نداره. اگه قبلاً با FlatList‌های سنگین دست و پنجه نرم کردید، می‌دونید چقدر این مهمه.

۴. Codegen

Codegen اون کد بویلرپلیت نیتیو رو که در اپلیکیشن‌های قدیمی عامل بسیاری از خطاهای زمان اجرا بود، حذف می‌کنه. شما یک بار اینترفیس TypeScript یا Flow تعریف می‌کنید و Codegen کد نیتیو مورد نیاز رو برای iOS (Objective-C++) و Android (C++/Kotlin) تولید می‌کنه.

مزیت اصلی: عدم تطابق نوع‌ها (type mismatches) به جای زمان اجرا (runtime)، در زمان ساخت (build time) شناسایی می‌شن. یعنی کرش‌های کمتر در Production و تجربه توسعه خیلی بهتر. از تجربه خودم بگم، تعداد باگ‌هایی که قبلاً فقط توی production پیداشون می‌کردیم به شدت کم شد.

پیش‌نیازهای مهاجرت

قبل از اینکه دست به کد بزنید، مطمئن بشید ابزارها و نسخه‌های زیر رو دارید:

  • React Native: حداقل نسخه ۰.۷۶ (نسخه ۰.۸۲ یا بالاتر توصیه می‌شه)
  • موتور Hermes: فعال (در نسخه‌های جدید پیش‌فرض هست)
  • Xcode: نسخه ۱۵ یا بالاتر برای iOS
  • Android Studio: نسخه Hedgehog با Kotlin 1.9+
  • Node.js: نسخه ۲۰ LTS
  • CocoaPods: نسخه ۱.۱۵ یا بالاتر

فرآیند مهاجرت گام‌به‌گام

گام ۱: ممیزی پروژه و وابستگی‌ها

قبل از تغییر حتی یک خط کد، باید بدونید پروژه‌تون چقدر آماده مهاجرته. جدی می‌گم — این مرحله رو رد نکنید. این ممیزی هفته‌ها عیب‌یابی رو صرفه‌جویی می‌کنه.

# بررسی وابستگی‌های قدیمی
npm outdated

# یا با yarn
yarn outdated

# لیست تمام وابستگی‌ها و نسخه‌هایشان
npx react-native info

برای بررسی سازگاری کتابخانه‌ها با معماری جدید، از React Native Directory استفاده کنید. فیلتر «New Architecture» رو فعال کنید تا ببینید کدوم کتابخانه‌ها از معماری جدید پشتیبانی می‌کنن.

اگه کتابخانه‌ای از معماری جدید پشتیبانی نمی‌کنه، چند تا گزینه دارید:

  1. ایشوهای GitHub اون رو بررسی کنید — شاید قبلاً کار سازگاری انجام شده باشه
  2. اگه نه، یک Issue یا PR ایجاد کنید
  3. به صورت موقت fork کنید و پیاده‌سازی TurboModule خودتون رو اضافه کنید
  4. کتابخانه جایگزینی پیدا کنید که از قبل سازگار باشه
  5. به عنوان آخرین راه‌حل، از لایه Interop استفاده کنید (که بعداً بیشتر توضیح می‌دم)

گام ۲: به‌روزرسانی React Native

از React Native Upgrade Helper برای مشاهده تفاوت‌ها بین نسخه فعلی و نسخه هدف استفاده کنید. یه نکته مهم: بیشتر از دو تا چهار نسخه یکجا جلو نرید. عیب‌یابی وقتی چند نسخه یکجا آپدیت می‌کنید به صورت نمایی سخت‌تر می‌شه و من این رو به سخت‌ترین شکل ممکن یاد گرفتم.

# به‌روزرسانی به آخرین نسخه React Native
npx react-native upgrade

# یا برای پروژه‌های Expo
npx expo install expo@latest --fix

نکته مهم: اکثر باگ‌هایی که هنگام مهاجرت باهاشون مواجه می‌شید، در نسخه‌های جدیدتر رفع شدن. پس قبل از شروع بهینه‌سازی‌های خاص اپلیکیشن، اول به آخرین نسخه پایدار به‌روزرسانی کنید.

گام ۳: فعال‌سازی معماری جدید

برای پروژه‌های React Native بدون Expo، فلگ‌های زیر رو تنظیم کنید:

// android/gradle.properties
newArchEnabled=true

// ios/Podfile — اضافه کردن در بالای فایل
ENV['RCT_NEW_ARCH_ENABLED'] = '1'

بعدش وابستگی‌های نیتیو رو مجدداً نصب کنید:

# برای iOS
cd ios && pod install && cd ..

# برای Android — ساخت مجدد
cd android && ./gradlew clean && cd ..

برای پروژه‌های Expo، با SDK 53 به بالا تمام پکیج‌های expo-* از معماری جدید پشتیبانی می‌کنن. SDK 54 (با React Native 0.81) آخرین نسخه‌ایه که از معماری قدیمی پشتیبانی می‌کنه.

گام ۴: مهاجرت ماژول‌های نیتیو سفارشی به TurboModules

اینجا جاییه که کار واقعی شروع می‌شه.

صادقانه بگم، این مهم‌ترین و زمان‌برترین بخش مهاجرته — حدود ۷۰ درصد از کل زمان مهاجرت صرف تبدیل ماژول‌های نیتیو سفارشی می‌شه. ابتدا باید یک فایل Spec (مشخصات) TypeScript برای هر ماژول بنویسید.

قواعد فایل Spec:

  • نام فایل باید با Native شروع بشه (مثلاً NativeLocalStorage.ts)
  • فایل باید یک آبجکت TurboModuleRegistrySpec اکسپورت کنه
  • پسوند فایل باید .ts یا .tsx باشه

بیاید با یه مثال عملی جلو بریم — تبدیل یک ماژول ذخیره‌سازی محلی:

// specs/NativeLocalStorage.ts
import type { TurboModule } from 'react-native';
import { TurboModuleRegistry } from 'react-native';

export interface Spec extends TurboModule {
  // متدهای همزمان — مقدار را بلافاصله برمی‌گردانند
  setItem(key: string, value: string): void;
  getItem(key: string): string | null;
  removeItem(key: string): void;
  clear(): void;

  // متد غیرهمزمان — Promise برمی‌گرداند
  getAllKeys(): Promise<string[]>;
}

export default TurboModuleRegistry.getEnforcing<Spec>(
  'NativeLocalStorage'
);

بعد، تنظیمات Codegen رو در package.json اضافه کنید:

// package.json
{
  "codegenConfig": {
    "name": "NativeLocalStorageSpec",
    "type": "modules",
    "jsSrcsDir": "specs",
    "android": {
      "javaPackageName": "com.myapp.localstorage"
    }
  }
}

حالا Codegen رو اجرا کنید تا کد نیتیو تولید بشه:

# تولید کد نیتیو Android
cd android && ./gradlew generateCodegenArtifactsFromSchema

# برای iOS — Codegen هنگام pod install اجرا می‌شود
cd ios && pod install

و در نهایت پیاده‌سازی نیتیو رو مطابق با اینترفیس تولیدشده بنویسید. اینجا مثال Android رو می‌بینید:

// android/app/src/main/java/com/myapp/NativeLocalStorageModule.kt
package com.myapp.localstorage

import android.content.SharedPreferences
import com.facebook.react.bridge.ReactApplicationContext
import com.myapp.NativeLocalStorageSpec

class NativeLocalStorageModule(
  reactContext: ReactApplicationContext
) : NativeLocalStorageSpec(reactContext) {

  override fun getName() = NAME

  private val prefs: SharedPreferences
    get() = reactApplicationContext
      .getSharedPreferences("app_storage", 0)

  override fun setItem(key: String, value: String) {
    prefs.edit().putString(key, value).apply()
  }

  override fun getItem(key: String): String? {
    return prefs.getString(key, null)
  }

  override fun removeItem(key: String) {
    prefs.edit().remove(key).apply()
  }

  override fun clear() {
    prefs.edit().clear().apply()
  }

  companion object {
    const val NAME = "NativeLocalStorage"
  }
}

گام ۵: مهاجرت کامپوننت‌های UI سفارشی به Fabric

اگه کامپوننت‌های نیتیو UI سفارشی دارید، باید اون‌ها رو هم به Fabric منتقل کنید. روند کار مشابه TurboModules هست: اول یه فایل Spec برای props کامپوننت تعریف می‌کنید و بعد Codegen بقیه کار رو انجام می‌ده.

// specs/NativeCustomButtonNativeComponent.ts
import type { ViewProps } from 'react-native';
import type {
  DirectEventHandler,
  Float,
} from 'react-native/Libraries/Types/CodegenTypes';
import codegenNativeComponent from
  'react-native/Libraries/Utilities/codegenNativeComponent';

interface NativeProps extends ViewProps {
  title: string;
  backgroundColor?: string;
  borderRadius?: Float;
  onPress?: DirectEventHandler<{}>;
}

export default codegenNativeComponent<NativeProps>(
  'CustomButton'
);

گام ۶: مدیریت تغییرات کد اپلیکیشن

چند تغییر مهم در سطح کد اپلیکیشن هست که باید حواستون بهشون باشه. بعضی‌هاشون ممکنه غافلگیرتون کنه.

حذف setNativeProps: یکی از پرکاربردترین API‌های منسوخ‌شده setNativeProps هست. این API مدل معماری جدید رو نقض می‌کنه چون مراحل رندرینگ رو دور می‌زنه و UI رو بین React Native و آنچه به کاربر نمایش داده می‌شه ناهماهنگ می‌کنه. جایگزینش ساده‌ست:

// قبل — استفاده از setNativeProps (دیگر کار نمی‌کند)
this.inputRef.setNativeProps({ text: 'Hello' });

// بعد — استفاده از state
const [text, setText] = useState('');
setText('Hello');

View Flattening: این یکی خیلی‌ها رو گیج می‌کنه. Fabric ممکنه کامپوننت‌هایی رو که برای layout نهایی غیرضروری تشخیص بده، بهینه‌سازی (حذف) کنه. اگه از ref روی View استفاده می‌کنید و ref همیشه null هست، احتمالاً View Flattening عامل اونه. راه‌حل ساده‌ست:

// اگر ref همیشه null است
<View ref={myRef} collapsable={false}>
  {/* محتوا */}
</View>

استفاده از Feature Flags: برای انتقال ایمن، از feature flags استفاده کنید. این کار بهتون اجازه می‌ده معماری جدید رو به صورت تدریجی و کنترل‌شده فعال کنید:

// utils/featureFlags.ts
import { Platform } from 'react-native';

export const useNewArchComponent = () => {
  // در فاز آزمایش فقط برای iOS فعال
  return Platform.OS === 'ios';
};

// در کامپوننت
const MyScreen = () => {
  const isNewArch = useNewArchComponent();

  return isNewArch
    ? <NewFabricComponent />
    : <LegacyComponent />;
};

گام ۷: تست جامع

بعد از فعال‌سازی معماری جدید، تست جامع اپلیکیشن حیاتیه. این مرحله رو سرسری نگیرید — من یک بار این اشتباه رو کردم و یه باگ نامحسوس تا production رفت.

  • تست‌های واحد Jest: اکثر تست‌های واحد بدون تغییر کار می‌کنن، اما mock‌های TurboModule ممکنه نیاز به به‌روزرسانی داشته باشن.
  • تست‌های یکپارچگی: تست‌های Detox و Maestro باید حتماً روی بیلدهای معماری جدید اجرا بشن. تفاوت‌های زمان‌بندی رندرینگ می‌تونه باعث flaky شدن تست‌هایی بشه که قبلاً بدون مشکل پاس می‌شدن.
  • پروفایلینگ عملکرد: قبل از مهاجرت، معیارهای پایه (baseline) اپلیکیشن رو ثبت کنید — زمان راه‌اندازی، مصرف حافظه، افت فریم. بعد از فعال‌سازی معماری جدید، دوباره اندازه‌گیری کنید و مقایسه کنید.
// مثال mock برای TurboModule در تست‌ها
jest.mock('react-native', () => {
  const RN = jest.requireActual('react-native');
  RN.TurboModuleRegistry = {
    getEnforcing: jest.fn((name) => {
      if (name === 'NativeLocalStorage') {
        return {
          setItem: jest.fn(),
          getItem: jest.fn(() => null),
          removeItem: jest.fn(),
          clear: jest.fn(),
          getAllKeys: jest.fn(() =>
            Promise.resolve([])
          ),
        };
      }
      return {};
    }),
  };
  return RN;
});

لایه Interop: سازگاری با عقب

معماری جدید شامل یک لایه سازگاری خودکار (Interop Layer) هست که امکان استفاده از کتابخانه‌هایی که هنوز برای معماری قدیمی نوشته شدن رو فراهم می‌کنه. عملاً به عنوان یک پل موقت عمل می‌کنه تا تیم‌ها بتونن به تدریج مهاجرت کنن.

ولی یه هشدار مهم: ترکیب ماژول‌های قدیمی و جدید می‌تونه باعث نشت حافظه (memory leak) بشه. لایه Interop رو به عنوان یه راه‌حل موقت ببینید، نه دائمی. هرچه زودتر ماژول‌های قدیمی رو مهاجرت کنید بهتره.

مهاجرت در پروژه‌های Expo

اگه از Expo استفاده می‌کنید، خبر خوب اینه که فرآیند مهاجرت خیلی ساده‌تره. از SDK 53 به بعد، تمام پکیج‌های expo-* از معماری جدید پشتیبانی می‌کنن (شامل حالت Bridgeless).

// app.json — Expo
{
  "expo": {
    "newArchEnabled": true,
    "plugins": [
      // پلاگین‌های Expo معمولاً خودکار سازگار هستند
      "expo-router",
      "expo-camera"
    ]
  }
}

SDK 54 (با React Native 0.81) آخرین نسخه‌ایه که از معماری قدیمی پشتیبانی می‌کنه — گزینه مناسبی برای مهاجرت تدریجی اگه عجله ندارید. SDK 55 آینده هم با React Native 0.83 عرضه خواهد شد.

زمان‌بندی و تخمین مهاجرت

یه سوال که همه می‌پرسن: «چقدر طول می‌کشه؟» جواب صادقانه: بستگی داره.

  • پروژه‌های ساده (بدون ماژول نیتیو سفارشی): ۱ تا ۲ هفته
  • پروژه‌های متوسط (با چند ماژول نیتیو): ۲ تا ۴ هفته
  • پروژه‌های بزرگ (با ماژول‌های نیتیو پیچیده): ۴ تا ۸ هفته

فازبندی پیشنهادی:

  1. فاز ممیزی و به‌روزرسانی (هفته ۱-۲): ممیزی وابستگی‌ها، به‌روزرسانی React Native و رفع مشکلات اولیه
  2. فاز مهاجرت TurboModules (هفته ۳-۶): نوشتن Spec‌ها، تبدیل ماژول‌ها و تست عملکرد
  3. فاز مهاجرت Fabric (هفته ۵-۷): تبدیل کامپوننت‌های UI سفارشی
  4. فاز انتشار (هفته ۷-۸): تست نهایی و انتشار تدریجی با استفاده از قابلیت Gradual Rollout اپ‌استورها

یه توصیه شخصی: همیشه ۲۰ تا ۳۰ درصد بافر زمانی اضافه در نظر بگیرید. مهاجرت‌ها تقریباً هیچوقت طبق برنامه پیش نمی‌رن.

چالش‌های رایج و راه‌حل‌ها

۱. کتابخانه‌های ناسازگار

سازگاری کتابخانه‌های شخص ثالث همچنان بزرگ‌ترین چالش مهاجرته. کتابخانه‌های اصلی اکوسیستم مثل React Navigation، Reanimated و Gesture Handler در سال ۲۰۲۶ از معماری جدید پشتیبانی کامل می‌کنن، اما برخی کتابخانه‌های قدیمی‌تر مثل react-native-fs ممکنه مشکل‌ساز باشن. قبل از شروع مهاجرت حتماً لیست کتابخانه‌هاتون رو چک کنید.

۲. زمان ساخت اولیه طولانی

اولین بیلد بعد از فعال‌سازی معماری جدید ممکنه روی iOS بسیار طولانی باشه — چون Xcode باید همه چیز رو با معماری جدید مجدداً کامپایل کنه. نگران نباشید، بیلدهای بعدی به سرعت عادی برمی‌گردن.

۳. صفحه سفید بدون خطا

تیم Shopify گزارش داد که خطاهای Fabric گاهی به صفحه سفید بدون هیچ پیام خطایی منجر می‌شن. این یکی واقعاً اعصاب‌خردکنه. برای دیباگ این مشکل، از ابزار React DevTools Profiler و لاگ‌های نیتیو (Logcat برای Android، Console برای iOS) استفاده کنید.

۴. تفاوت‌های State Batching

معماری جدید آپدیت‌های state رو متفاوت batch می‌کنه. اگه رفتار غیرمنتظره‌ای در آپدیت‌های state مشاهده کردید، ممکنه به دلیل این تفاوت باشه. از flushSync برای اجبار آپدیت فوری استفاده کنید.

ابزارهای مفید برای مهاجرت

  • React Native Upgrade Helper: ابزار آنلاین برای مشاهده تفاوت‌های بین نسخه‌ها — این رو حتماً بوکمارک کنید
  • React Native Directory: بررسی سازگاری کتابخانه‌ها با معماری جدید
  • Flipper / React DevTools: پروفایلینگ عملکرد قبل و بعد از مهاجرت
  • react-native-builder-bob: ابزار ساخت و scaffold کتابخانه‌های جدید با پشتیبانی معماری جدید
  • RNNewArchitectureApp: ریپوزیتوری GitHub با مثال‌های گام‌به‌گام مهاجرت

پرسش‌های متداول (FAQ)

آیا می‌توانم از معماری قدیمی React Native در سال ۲۰۲۶ استفاده کنم؟

کوتاه و مفید: خیر. با انتشار React Native 0.82، معماری قدیمی به طور دائمی غیرفعال شده. نسخه‌های قبل از ۰.۸۲ هنوز کار می‌کنن اما آپدیت‌های مهم یا امنیتی دریافت نمی‌کنن و بسیاری از کتابخانه‌های جامعه هم دارن پشتیبانی از معماری قدیمی رو حذف می‌کنن.

تفاوت JSI با Bridge قدیمی React Native چیست؟

Bridge قدیمی از سریال‌سازی JSON و ارتباط غیرهمزمان استفاده می‌کرد — هر پیام باید به JSON تبدیل، در صف قرار داده و تجزیه می‌شد. JSI این واسطه رو حذف کرده و امکان ارتباط مستقیم و همزمان بین جاوااسکریپت و کد نیتیو رو از طریق ارجاعات حافظه C++ فراهم می‌کنه. نتیجه: سرعت بسیار بالاتر، مصرف حافظه کمتر و امکان فراخوانی‌های همزمان.

آیا مهاجرت به معماری جدید اپلیکیشن را خراب می‌کند؟

اگه مراحل مهاجرت رو درست طی کنید، نه. استفاده از لایه Interop سازگاری با کتابخانه‌های قدیمی رو حفظ می‌کنه. انتشار تدریجی و feature flags بهتون اجازه می‌دن مشکلات رو قبل از انتشار عمومی شناسایی کنید. البته همیشه توصیه می‌کنم قبل از انتشار عمومی، حتماً یه دوره بتا تستینگ داشته باشید.

چقدر طول می‌کشد تا پروژه‌ام را به معماری جدید منتقل کنم؟

بسته به پیچیدگی پروژه، ۱ تا ۸ هفته. پروژه‌های بدون ماژول نیتیو سفارشی حدود ۱ تا ۲ هفته و پروژه‌های بزرگ با ماژول‌های نیتیو پیچیده ۴ تا ۸ هفته زمان نیاز دارن. حدود ۷۰ درصد زمان مهاجرت صرف تبدیل ماژول‌های نیتیو سفارشی به TurboModules می‌شه.

آیا پروژه‌های Expo هم باید مهاجرت کنند؟

بله، ولی فرآیند خیلی ساده‌تره. از Expo SDK 53 به بعد، تمام پکیج‌های expo-* از معماری جدید پشتیبانی می‌کنن. عملاً فقط کافیه newArchEnabled: true رو در app.json تنظیم کنید. اگه ماژول‌های نیتیو سفارشی از طریق Expo Modules API نوشته شده باشن، معمولاً به صورت خودکار سازگارن و نیاز به کار خاصی نیست.

درباره نویسنده Editorial Team

Our team of expert writers and editors.