@samitouri / QOS-React-2 / commits / b14d7fa4b8

Add support for setNativeProps to Fabric (#25737)

Add support for `setNativeProps` in Fabric to make migration to the new architecture easier. The React Native part of this has already landed in the core and iOS in https://github.com/facebook/react-native/commit/1d3fa40c59b234f21f516db85c322ec0ed0311e0. It is still recommended to move away from `setNativeProps` because the API will not work with future features.

Samuel Susla committed Dec 9, 2022 at 14:43 UTC b14d7fa4b88dad5f0017d084e462952c700aa2ad
4 files changed +18 -16
packages/react-native-renderer/src/ReactFabricHostConfig.js
+11 -5
@@ -18,7 +18,10 @@ import type {
18 TouchedViewDataAtPoint,
19 } from './ReactNativeTypes';
20
21 -import {mountSafeCallback_NOT_REALLY_SAFE} from './NativeMethodsMixinUtils';
21 +import {
22 + mountSafeCallback_NOT_REALLY_SAFE,
23 + warnForStyleProps,
24 +} from './NativeMethodsMixinUtils';
25 import {create, diff} from './ReactNativeAttributePayload';
26
27 import {dispatchEvent} from './ReactFabricEventEmitter';
@@ -52,6 +55,7 @@ const {
55 unstable_DefaultEventPriority: FabricDefaultPriority,
56 unstable_DiscreteEventPriority: FabricDiscretePriority,
57 unstable_getCurrentEventPriority: fabricGetCurrentEventPriority,
58 + setNativeProps,
59 } = nativeFabricUIManager;
60
61 const {get: getViewConfigForType} = ReactNativeViewConfigRegistry;
@@ -208,12 +212,14 @@ class ReactFabricHostComponent {
212
213 setNativeProps(nativeProps: Object) {
214 if (__DEV__) {
211 - console.error(
212 - 'Warning: setNativeProps is not currently supported in Fabric',
213 - );
215 + warnForStyleProps(nativeProps, this.viewConfig.validAttributes);
216 }
217 + const updatePayload = create(nativeProps, this.viewConfig.validAttributes);
218
216 - return;
219 + const {stateNode} = this._internalInstanceHandle;
220 + if (stateNode != null && updatePayload != null) {
221 + setNativeProps(stateNode.node, updatePayload);
222 + }
223 }
224
225 // This API (addEventListener, removeEventListener) attempts to adhere to the
packages/react-native-renderer/src/__mocks__/react-native/Libraries/ReactPrivate/InitializeNativeFabricUIManager.js
+2
@@ -117,6 +117,8 @@ const RCTFabricUIManager = {
117
118 dispatchCommand: jest.fn(),
119
120 + setNativeProps: jest.fn(),
121 +
122 sendAccessibilityEvent: jest.fn(),
123
124 registerEventHandler: jest.fn(function registerEventHandler(callback) {}),
packages/react-native-renderer/src/__tests__/ReactFabricHostComponent-test.internal.js
+4 -10
@@ -38,7 +38,7 @@ function mockRenderKeys(keyLists) {
38
39 const mockContainerTag = 11;
40 const MockView = createReactNativeComponentClass('RCTMockView', () => ({
41 - validAttributes: {},
41 + validAttributes: {foo: true},
42 uiViewClassName: 'RCTMockView',
43 }));
44
@@ -200,21 +200,15 @@ describe('measureLayout', () => {
200 });
201
202 describe('setNativeProps', () => {
203 - test('setNativeProps(...) emits a warning', () => {
203 + test('setNativeProps(...) invokes setNativeProps on Fabric UIManager', () => {
204 const {
205 UIManager,
206 } = require('react-native/Libraries/ReactPrivate/ReactNativePrivateInterface');
207
208 const [[fooRef]] = mockRenderKeys([['foo']]);
209 + fooRef.setNativeProps({foo: 'baz'});
210
210 - expect(() => {
211 - fooRef.setNativeProps({});
212 - }).toErrorDev(
213 - ['Warning: setNativeProps is not currently supported in Fabric'],
214 - {
215 - withoutStack: true,
216 - },
217 - );
211 expect(UIManager.updateView).not.toBeCalled();
212 + expect(nativeFabricUIManager.setNativeProps).toHaveBeenCalledTimes(1);
213 });
214 });
scripts/flow/react-native-host-hooks.js
+1 -1
@@ -186,7 +186,7 @@ declare var nativeFabricUIManager: {
186 payload: Object,
187 ) => void,
188 ) => void,
189 -
189 + setNativeProps: (node: Object, nativeProps: Object) => Object,
190 dispatchCommand: (node: Object, command: string, args: Array<any>) => void,
191 sendAccessibilityEvent: (node: Object, eventTypeName: string) => void,
192