Andrei Calazans

React Native Weekly - W25 2021

☕️ 5 min read

Welcome to the 14th edition of React Native Weekly. This is the retrospect of week 25 of 2021.

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

Cleaning up in anticipation to removing the Picker Component

The Picker component was selected to be removed from core during the Lean Core initiative, it is now recommended you use one in the community packages.

This week there were a few commits that removed the Picker Component from the examples:

f12f0e679dd Remove Picker from ScrollView examples
c780366eeed Remove Picker from Android Permissions example
70727a5d449 Remove Picker from TextLegend example
b22a6d6e9d9 Remove Picker from Modal example
572deaebd9c Remove usage of Picker from Accessibility Example
65740723d98 Remove Picker from XHR example
625d9e5090a Remove PickerAndroidTestModule

Avoid re-encoding images when uploading local files [FIX][iOS]

Arthur Lee arthur.lee@chime.com summarizes in his PR that when you upload a local image file the module behind it (RCXTNetowrkTask) ends up using RCTLocalAssetImageLoader to load that image, however during this load it puts that image onto a UIImage and re-encodes it using UIImageJPEGRepresentation with maximum compression quality. This inflates the size of the JPG specially for images previously compressed.

His commit fixes the issue by always using the RCTFileRequestHandler for file loads irregardless if it is an image, this module puts the file into a NSData which is the required type for multipart data appending.

Fix NullPointerException during tear down of RN Android

This diff prevents a NullPointerException caused by a race condition in the tear down of React Native.

diff --git a/ReactAndroid/src/main/java/com/facebook/react/ReactInstanceManager.java b/ReactAndroid/src/main/java/com/facebook/react/ReactInstanceManager.java
index 2b0d89aa19a..b46b1b71b2c 100644
--- a/ReactAndroid/src/main/java/com/facebook/react/ReactInstanceManager.java
+++ b/ReactAndroid/src/main/java/com/facebook/react/ReactInstanceManager.java
@@ -1340,7 +1340,12 @@ public class ReactInstanceManager {
               new ComponentNameResolver() {
                 @Override
                 public String[] getComponentNames() {
-                  return getViewManagerNames().toArray(new String[0]);
+                  List<String> viewManagerNames = getViewManagerNames();
+                  if (viewManagerNames == null) {
+                    FLog.e(TAG, "No ViewManager names found");
+                    return new String[0];
+                  }
+                  return viewManagerNames.toArray(new String[0]);
                 }
               });
       catalystInstance.setGlobalVariable("__fbStaticViewConfig", "true");

Add title to DevMenu

After this change, the DialogBox will have a title. This should help distinguish between the Bridgeless DevMenu and the Bridge DevMenu.

DevMenu: Change “Toggle Inspector” to Show/Hide Element Inspector

This makes the element inspector button consistent with the Fast Refresh, Perf Monitor and other buttons in the DevMenu

diff --git a/ReactAndroid/src/main/res/devsupport/values/strings.xml b/ReactAndroid/src/main/res/devsupport/values/strings.xml
index 3571c835e31..9ebb11b0830 100644
--- a/ReactAndroid/src/main/res/devsupport/values/strings.xml
+++ b/ReactAndroid/src/main/res/devsupport/values/strings.xml
@@ -16,7 +16,8 @@
   <string name="catalyst_hot_reloading_stop" project="catalyst" translatable="false">Disable Fast Refresh</string>
   <string name="catalyst_hot_reloading_auto_disable" project="catalyst" translatable="false">Disabling Fast Refresh because it requires a development bundle.</string>
   <string name="catalyst_hot_reloading_auto_enable" project="catalyst" translatable="false">Switching to development bundle in order to enable Fast Refresh.</string>
-  <string name="catalyst_inspector" project="catalyst" translatable="false">Toggle Inspector</string>
+  <string name="catalyst_inspector" project="catalyst" translatable="false">Show Element Inspector</string>
+  <string name="catalyst_inspector_stop" project="catalyst" translatable="false">Hide Element Inspector</string>
   <string name="catalyst_perf_monitor" project="catalyst" translatable="false">Show Perf Monitor</string>
   <string name="catalyst_perf_monitor_stop" project="catalyst" translatable="false">Hide Perf Monitor</string>
   <string name="catalyst_settings" project="catalyst" translatable="false">Settings</string>

Take RTL into account in scrollTo view command

ScrollView’s scrollTo command doesn’t work in RTL. It sets the offset from left of the screen instead of right. This diff fixes this for Fabric only.

Log ImageSource uris that are not using Facebook domain

This diff adds logging to uncover what are the ReactNative screens that are rendering images using NON-Facebook domains

diff --git a/Libraries/Image/Image.android.js b/Libraries/Image/Image.android.js
index 81df06415c1..76d3f56306d 100644
--- a/Libraries/Image/Image.android.js
+++ b/Libraries/Image/Image.android.js
@@ -13,7 +13,7 @@ import ImageViewNativeComponent from './ImageViewNativeComponent';
 import * as React from 'react';
 import StyleSheet from '../StyleSheet/StyleSheet';
 import TextAncestor from '../Text/TextAncestor';
-
+import ImageSourceInjection from './ImageSourceInjection';
 import ImageAnalyticsTagContext from './ImageAnalyticsTagContext';
 import flattenStyle from '../StyleSheet/flattenStyle';
 import resolveAssetSource from './resolveAssetSource';
@@ -132,8 +132,13 @@ let Image = (props: ImagePropsType, forwardedRef) => {
     props.loadingIndicatorSource,
   );
 
-  if (source && source.uri === '') {
-    console.warn('source.uri should not be an empty string');
+  if (source) {
+    const uri = source.uri;
+    if (uri === '') {
+      console.warn('source.uri should not be an empty string');
+    } else if (ImageSourceInjection.unstable_enableUriAnalytics) {
+      ImageSourceInjection.unstable_enableUriAnalytics(uri);
+    }
   }
 
   if (props.src) {

This is likely just a temporary analytics injections Facebook needs for their production app. Since we can’t see the injected code we don’t know exactly what it is logging.

Bump Flipper to 0.93 (#31708)

Commit

Resolve race condition in usage/teardown of EventEmitterWrapper

This change is a rather funny story of the cascading effect of fixes 😂:

This crash is caused by D29020768 which was landed to fix T92179998, which was in turn caused by D28938637.

Summary:

In stopSurface we destroy these EventEmitters which is not a threadsafe operation. Wrap usage and destruction of these wrappers to prevent crashes.

This was not the only change, they are struggling with null pointers being passed around and called unchecked. Joshua Gross joshuagross@fb.com in this PR tries to make the entire EventEmitter module more resilient around null pointers.

Flipper Update

This commit bumps flipper deps to 0.91 to support XCode 12.5 out of the box (#31562)

Finding contributors for the React Native ecosystem

In a recent tweet, Eli White highlighted how he struggles to find contributors to React Native. Specially experienced iOS and Android developers. If you have a suggestion tweet at him or become a contributor yourself?

Gestures don’t work on Android inside a native Modal component

A tweet from Emma Dawson

Emma Dawson @emmalearnscode Ugh, gestures in react native are complicated Grimacing face worked perfectly in iOS and not at all on android. Turns out gestures don’t work on android if you use them inside the native modal component Woman facepalming so we had to build our own component

Multifaceted graph perspective of a React Native Developer

Lorenzo made an interesting graph that displays everything in the React Native ecosystem from the perspective of a developer.

That Is It!

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