What I did for upgrading React Native to 0.79.1 from 0.74.2

What I did for upgrading React Native to 0.79.1 from 0.74.2

Hi, it's Takuya here, the developer of Inkdrop – a Markdown note-taking app that supports syncing and offline-first capabilities, built with React Native.

Bumping up the React Native versions has always been hard, and this time wasn't an exception, especially because it involved migrating from the old to the new architecture.
So, I'd like to share what I did for this upgrade.

VLOG:

The old RN is no longer able to build with Xcode >= 16.3

Xcode 16.3 and undefined template ‘std::char_traits<unsigned char>’ prevent building the app · Issue #50411 · facebook/react-native
Description Xcode 16.3 removes the base template for std::char_traits: https://developer.apple.com/documentation/xcode-release-notes/xcode-16_3-release-notes This prevents to build iOS app with new…

As reported here, Xcode 16.3 removed the base template for std::char_traits.
This change prevents to build iOS app.
So, I could't build my app with React Native 0.74 since it is out of the support window.

So, I had no choice but to upgrade React Native.

Use the upgrade helper

My first step was to visit the React Native Upgrade Helper, which provides diffs between your current version and the target version.
The diffs in my case looked simple. I manually applied them to my project.

After that, I ran into this error when building the app:

[!] CocoaPods could not find compatible versions for pod "RCT-Folly"

I deleted the Podfile.lock file and ran pod install again. Then, it solved.

Native module migration

My app has a custom native module for supporting PDF export from an embedded webview.
I shared how to get an instance of the native view components in a custom module here:

How to get an instance of the Fabric view component on React Native (>= 0.73)
Hello, it’s Takuya here. The mobile version of my app Inkdrop is built on top of React Native. It is a Markdown note-taking app, which renders notes in webview. The notes can include images, and currently it can display them blazingly fast because of the hack I shared here a

Since then, there have been some breaking changes in internal modules, so I updated the code accordingly.

On Android, reactContext.fabricUIManager is now deprecated.
Here is the new approach:

// Old approach that no longer worked
val view = reactContext.fabricUIManager?.resolveView(webViewReactTag)

// New approach with UIManagerHelper
val uiManager = UIManagerHelper.getUIManager(reactContext, UIManagerType.DEFAULT)
val view = uiManager?.resolveView(webViewReactTag)

On iOS, the way to get the RCTHost object has been changed like so:

// Old
AppDelegate *delegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
RCTHost *reactHost = (RCTHost*)[delegate.rootViewFactory valueForKey:@"_reactHost"];

// New
id<InkdropAppDelegate> delegate = (id<InkdropAppDelegate>)[[UIApplication sharedApplication] delegate];
RCTReactNativeFactory* factory = [delegate reactNativeFactory];
RCTHost *reactHost = factory.rootViewFactory.reactHost;

SafeAreaView is broken

In the sidebar, SafeAreaView wasn't working correctly as seen in the screenshot above.
I had to add SafeAreaProvider in the drawerContent prop like so:

<Drawer.Navigator
  initialRouteName="Main"
  screenOptions={{
    // ...
  }}
  drawerContent={props => (
    <SafeAreaProvider>
      <Sidebar {...props} />
    </SafeAreaProvider>
  )}
>

Bumping up op-sqlite

The app stores data using PouchDB and SQLite as its backing store.
For a SQLite adapter, I use op-sqlite.

There was a breaking change when upgrading it from v6 to v12.
To get it to work as before, you have to change the method as the following:

// Old
const result = await db.executeAsync(query, params);

// New
const result = await db.execute(query, params);

Fixing a bug in react-native-quick-crypto

I made a small contribution to fix a bug in the crypto library:

Fix inconsistent return type of pbkdf2 by craftzdog · Pull Request #669 · margelo/react-native-quick-crypto
Hi, I found a regression in 0.x. pbkdf2Sync has been returning Buffer, but v0.7.13 returns Uint8Array. pbkdf2 still returns Buffer. This commit broke the behavior: 8894983 But I couldn&#39;t find a…

Updating the pouchdb adapter

I've published a PouchDB adapter for SQLite and shared it in this article:

The fastest way to use PouchDB on React Native 0.73+
Hi, it’s Takuya here. I’ve been updating the mobile version of Inkdrop, which is built with React Native. It is a simple Markdown note-taking app, which supports syncing notes with the server and offer an offline-first viewing and editing experience. To accomplish this, I’ve been using PouchDB, the JavaScript-based database

This adapter has been broken on the recent RN versions, so I updated it.
This PR helped me do so (Thanks Gufeng Shen):

Bump up op-sqlite version for react native v0.76 by tearfulDalvik · Pull Request #37 · craftzdog/pouchdb-adapter-react-native-sqlite
#35 In React Native 0.76.3, createError from pouchdb-errors would throw an exception. To handle this, I catch all errors. However, this causes specific errors like MISSING_DOC to be converted into…

I've tested it on my app and it worked fine, so I publishded it:

v4.1.0 by craftzdog · Pull Request #50 · craftzdog/pouchdb-adapter-react-native-sqlite
This pull request introduces multiple updates, including dependency upgrades, code refactoring, and configuration changes to enhance compatibility and maintainability. Key highlights include the ad…

React Navigation issues

In RN 0.79, some navigations didn't work for some reason.
Maybe this was due to nested navigators.
I found that using createNavigationContainerRef solved it.
It lets you get the root navigation regardless of the context.
You can use it like so:

// Create a reference
const navigationRef = createNavigationContainerRef();

export default function App() {
  return (
    <NavigationContainer ref={navigationRef}>{/* ... */}</NavigationContainer>
  );
}

export function navigate(name, params) {
  if (navigationRef.isReady()) {
    navigationRef.navigate(name, params);
  }
}

For more information, check out the docs: https://reactnavigation.org/docs/navigating-without-navigation-prop/

iOS App Connect Warning

After updating RN, App Connect started sending this warning when submitting the app:

ITMS-90078: Missing potentially required entitlement - Your app, or a library that's included in your app, uses Apple Push Notification service (APNs) registration APIs...

I greped the source and found that the React Native core uses it:

node_modules/react-native/Libraries/PushNotificationIOS/RCTPushNotificationManager.h:+ (void)didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken;
node_modules/react-native/Libraries/PushNotificationIOS/RCTPushNotificationManager.h: * notification.
node_modules/react-native/Libraries/PushNotificationIOS/RCTPushNotificationManager.h: * To process notifications received while the app is in the foreground, call this method from
node_modules/react-native/Libraries/PushNotificationIOS/RCTPushNotificationManager.h: * the push notification should be shown; to match prior behavior which does not show foreground notifications, use
node_modules/react-native/Libraries/PushNotificationIOS/RCTPushNotificationManager.h: * If you need to determine if the notification is remote, check that notification.request.trigger
node_modules/react-native/Libraries/PushNotificationIOS/RCTPushNotificationManager.h:+ (void)didReceiveNotification:(UNNotification *)notification;
node_modules/react-native/Libraries/PushNotificationIOS/RCTPushNotificationManager.h:+ (void)didReceiveRemoteNotification:(NSDictionary *)notification
node_modules/react-native/Libraries/PushNotificationIOS/RCTPushNotificationManager.h:+ (void)setInitialNotification:(UNNotification *)notification;

However, my app doesn't use APNs and PushNotificationIOS looks already deprecated. Maybe I can ignore the warning:

If there are any ways to avoid this warning, please let me know 🙏


That's it! Most issues were app-specific, but I hope it's helpful.
The new architecture is much more stable than before thanks to the community's effort. Also, it feels like very performant like the faster launch speed.

I will keep focusing on the app quality for providing a great note-taking experience!

Inkdrop - Note-taking App with Robust Markdown Editor
The Note-Taking App with Robust Markdown Editor

Read more