skip to content
Andrei Calazans

React Native Weekly - W17 2021

/ 6 min read

Welcome to the sixth edition of React Native Weekly = )

Reach out to me via Twitter if you have any feedback, and don’t forget to subscribe!

Defensive Programming - NativeEventEmitter Checks Add & Remove Listener

Now, the NativeEventEmitter checks if the native module it received when instantiated has add and remove event listener methods.

+    const hasAddListener =
+      !!nativeModule && typeof nativeModule.addListener === 'function';
+    const hasRemoveListeners =
+      !!nativeModule && typeof nativeModule.removeListeners === 'function';
+
+    if (nativeModule && hasAddListener && hasRemoveListeners) {

Commit

Bump Gradle Wrapper To 6.8.3

This is preparation for Gradle 7.0 version, which supports Apple Silicon natively.

Commit

RuntimeScheduler

The Runtime Scheduler continues to be worked on, the efforts here are all related to Fabric - the asynchronous scheduling system that has priority queues. Most of the work seems to happen in coordination with the React Core team.

Some updates were:

Pass hardcoded false argument to scheduled callbacks

Scheduled callback function expects a boolean param to indicate if a callback timed out. React Core team will remove it, thus they are hardcoding it for now.

 void Task::operator()(jsi::Runtime &runtime) const {
+  // Cancelled task doesn't have a callback.
   if (callback_) {
-    // Cancelled task doesn't have a callback.
-    callback_.value().call(runtime, {});
+    // Callback in JavaScript is expecting a single bool parameter.
+    // React team plans to remove it and it is safe to pass in
+    // hardcoded false value.
+    callback_.value().call(runtime, {false});
   }
 }

Implement task continuation

Commit comment:

Scheduler’s callback have option to add more work inside callback. This work stays on top of the priority queue and gives React ability to flush all work synchronously if need.

This diff adds use of shouldYield_ to the workLoop. For now, it always evaluates to false. In the future when we allow access to the scheduler to native, it will allow yielding.

Commit

Fix for ‘An Unexpected error occurred’ caused by DatePickerDialog.

This was a fix introduced because of a error they caught in the Messenger Kids app. The main change is just handling the UI update within the UI thread, on Android you can only make UI changes within the UI thread.

--- a/ReactAndroid/src/main/java/com/facebook/react/modules/datepicker/DatePickerDialogModule.java
+++ b/ReactAndroid/src/main/java/com/facebook/react/modules/datepicker/DatePickerDialogModule.java

...
+    activity.runOnUiThread(
+        new Runnable() {
+          @Override
+          public void run() {

[iOS] Fix InputAccessoryView disappearing when inputAccessoryViewID exists

Commit comment:

InputAccessoryView disappears on Fabric (not Paper) when the text prop changes.

Bridgeless support for RCTSourceCode

Commit

I’m not 100% sure how this can be or will be used, but it is simply allowing you to set a URL for your JS bundle instead of a bridge. Let’s see if future updates tells us more.

Fix crash - check if backgroundColor is null before trying to fetch it in ViewProps isLayoutOnly

Commit comment:

Summary: Noticed while working in MobileHome with android device, when interacting with the Tasks change progress/priority components (MobileHomeTasksDetailsSelectorToken), which provides borderRadius style and backgroundColor: ifSelected ? value : null, and when backgroundColor is null, the line changed in this diff crashes (throwing the NoSuchKeyException at ReadableNativeMap:110 [because of isNull check on ReadableNativeMap:107])

iOS 14 Support new DatePicker styles

This was mostly about adding if checks for iOS version like:

+ if (@available(iOS 13.4, *)) {

And setting the view.preferredDatePickerStyle with the right value.

Some height updates to the overall look also happened.

Introduce drainMicrotasks to JSI

JavaScript VMs (JSVMs) implement internal Microtask (a.k.a. Job in ECMA262) queue to handle job queue (like promises).

This commit implements a new JSI API drainMicrotasks to define how hosts may integrate with the JSVMs’ internal microtask queue.

Xuan Huang (jsx@fb.com>) documented his changes quite well with extensive comments around his decisions. If you are curious check out the commit and the jsi.h file which has more comments about the drainMicrotasks.

Here is an short snippet of something Xuan explained:

Notes on the existing APIs from JSVMs

The presence of such queue and APIs to operate on them are ubiquitous:

  • Hermes: Runtime::drainJobs
  • V8: MicrotaskQueue::PerformCheckpoint
  • JSC: VM::drainMicrotasks
  • QuickJS: JS_ExecutePendingJob

The only exception is ChakraCore, which requires hosts to provide the queue and set up the JsSetPromiseContinuationCallback, but a JSI implementation can provide that queue trivially.

Perform Engine Microtasks in JSIExecutor

Xuan Huang (jsx@fb.com>) did further work on the Engine Microtasks:

This diff introduce a helper performMicrotaskCheckpoint to repetitively invoke jsi::Runtime::drainMicrotasks to exhaust the microtasks queue provided by JS VMs

Refactor: Move RuntimeExecutor into Instance.cpp

While the change is trivial, the commit message explains something interesting about the pieces of React Native’s architecture such as NativeToJsBridge, RuntimeExecutor, and Instance.

RuntimeExecutor is currently declared inside NativeToJsBridge. It doesn’t need to be: Instance.cpp can use NativeToJsBridge::runOnExecutorQueue to schedule work on the JS Thread. So, this diff moves RuntimeExecutor out of NativeToJsBridge into Instance.cpp. Now, both the JS CallInvoker and the RuntimeExecutor are declared in the same file.

Add flushing to RuntimeExecutor

commit

Motivation

With the bridge, every call into JS flushes the queue of NativeModule calls. Fabric bypasses this mechanism, because it uses a RuntimeExecutor that schedules work directly on the JavaScript thread. This diff makes Fabric’s RuntimeExecutor also flush the queue of NativeModule calls.

This likely won’t fix anything in Fabric, because we don’t execute any async NativeModule calls on Fabric. However, this is necessary for the drainMicrotask work we’re doing

--- a/ReactCommon/cxxreact/Instance.cpp
+++ b/ReactCommon/cxxreact/Instance.cpp
+                  if (shouldFlush) {
+                    executor->flush();
+                  }

Removed getNode() from Animated Component Refs

commit

This was predicted since there were warnings already.

diff --git a/Libraries/Animated/createAnimatedComponent.js b/Libraries/Animated/createAnimatedComponent.js
index 45859bb111..c86e63cd88 100644
--- a/Libraries/Animated/createAnimatedComponent.js
+++ b/Libraries/Animated/createAnimatedComponent.js
@@ -198,19 +198,6 @@ function createAnimatedComponent<Props: {+[string]: mixed, ...}, Instance>(
       setLocalRef: ref => {
         this._prevComponent = this._component;
         this._component = ref;
-
-        // TODO: Delete this in a future release.
-        if (ref != null && ref.getNode == null) {
-          ref.getNode = () => {
-            console.warn(
-              '%s: Calling `getNode()` on the ref of an Animated component ' +
-                'is no longer necessary. You can now directly use the ref ' +
-                'instead. This method will be removed in a future release.',
-              ref.constructor.name ?? '<<anonymous>>',
-            );
-            return ref;
-          };
-        }
       },
     });
 

How Hermes shranked their heap by 30%

Tzvetan Mikov, Hermes’ tech lead, shared some insight into how they reduced the engine’s heap usage by 30%. He explained they introduced a 32-bit value encoding for values stored in the heap since now all values require 64-bit encoding.

See tweet

Callstack’s Post On Hermes’ Performance On iOS

link

Beatgig - A Web, iOS, and Android codebase using React Native

Fernando Rojo is always showing off cool animations he accomplishes with his library Moti, this time he shared cross-platform app he is building which looks amazing.

Tweet

Removing Console Logs In Production

Evan shared with us that you can set Metro’s drop_console value to true and have all console logs removed.

Tweet

That Is It!

That’s it for this week. If you want to see more checkout last week’s post here. Subscribe to get notified when new posts are out = )