mirror of
https://github.com/facebook/react-native.git
synced 2025-11-01 09:14:26 +00:00
Add definition of setNativeProps in NativeDOM and use it if available (#51343)
Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/51343 Changelog: [internal] This implements `setNativeProps` as a method in the `NativeDOM` C++ TurboModule, so we can replace usages of the method from `FabricUIManager`. Reviewed By: javache Differential Revision: D74800815 fbshipit-source-id: cf3c2d4b75c8d30e2528f96d4d63318e1366096a
This commit is contained in:
committed by
Facebook GitHub Bot
parent
89e21b866a
commit
c7611e0d79
+54
@@ -14,6 +14,7 @@ import '@react-native/fantom/src/setUpDefaultReactNativeEnvironment';
|
||||
import type {HostInstance} from 'react-native';
|
||||
|
||||
import ReactNativeElement from '../../../../src/private/webapis/dom/nodes/ReactNativeElement';
|
||||
import {getRawNativeDOMForTests} from '../../../../src/private/webapis/dom/nodes/specs/NativeDOM';
|
||||
import TextInputState from '../../../Components/TextInput/TextInputState';
|
||||
import View from '../../../Components/View/View';
|
||||
import ReactFabricHostComponent from '../ReactFabricHostComponent';
|
||||
@@ -395,6 +396,59 @@ export default function setUpTests({isModern}: {isModern: boolean}) {
|
||||
.toJSX(),
|
||||
).toEqual(<rn-view testID={'second test id'} />);
|
||||
});
|
||||
|
||||
// TODO: delete when NativeDOM.setNativeProps is NOT nullable.
|
||||
// This logic is to ensure compatibility with old app versions without the native module method.
|
||||
if (isModern) {
|
||||
let RawNativeDOM;
|
||||
let originalSetNativeProps;
|
||||
|
||||
beforeAll(() => {
|
||||
RawNativeDOM = nullthrows(getRawNativeDOMForTests());
|
||||
originalSetNativeProps = RawNativeDOM.setNativeProps;
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
// $FlowExpectedError[cannot-write]
|
||||
RawNativeDOM.setNativeProps = originalSetNativeProps;
|
||||
});
|
||||
|
||||
it('should propagate changes to the host component (when NativeDOM.setNativeProps is not available)', () => {
|
||||
// $FlowExpectedError[cannot-write]
|
||||
RawNativeDOM.setNativeProps = null;
|
||||
|
||||
expect(RawNativeDOM.setNativeProps).toBeNull();
|
||||
|
||||
const root = Fantom.createRoot();
|
||||
const nodeRef = React.createRef<HostInstance>();
|
||||
|
||||
Fantom.runTask(() => {
|
||||
root.render(<View ref={nodeRef} testID="first test id" />);
|
||||
});
|
||||
|
||||
expect(
|
||||
root
|
||||
.getRenderedOutput({
|
||||
props: ['testID'],
|
||||
})
|
||||
.toJSX(),
|
||||
).toEqual(<rn-view testID={'first test id'} />);
|
||||
|
||||
const element = nullthrows(nodeRef.current);
|
||||
|
||||
Fantom.runTask(() => {
|
||||
element.setNativeProps({testID: 'second test id'});
|
||||
});
|
||||
|
||||
expect(
|
||||
root
|
||||
.getRenderedOutput({
|
||||
props: ['testID'],
|
||||
})
|
||||
.toJSX(),
|
||||
).toEqual(<rn-view testID={'second test id'} />);
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@@ -25,12 +25,15 @@ namespace facebook::react {
|
||||
|
||||
#pragma mark - Private helpers
|
||||
|
||||
static UIManager& getUIManagerFromRuntime(facebook::jsi::Runtime& runtime) {
|
||||
return UIManagerBinding::getBinding(runtime)->getUIManager();
|
||||
}
|
||||
|
||||
static RootShadowNode::Shared getCurrentShadowTreeRevision(
|
||||
facebook::jsi::Runtime& runtime,
|
||||
SurfaceId surfaceId) {
|
||||
auto& uiManager =
|
||||
facebook::react::UIManagerBinding::getBinding(runtime)->getUIManager();
|
||||
auto shadowTreeRevisionProvider = uiManager.getShadowTreeRevisionProvider();
|
||||
auto shadowTreeRevisionProvider =
|
||||
getUIManagerFromRuntime(runtime).getShadowTreeRevisionProvider();
|
||||
return shadowTreeRevisionProvider->getCurrentRevision(surfaceId);
|
||||
}
|
||||
|
||||
@@ -459,4 +462,15 @@ void NativeDOM::measureLayout(
|
||||
jsi::Value{rt, rect.height}});
|
||||
}
|
||||
|
||||
#pragma mark - Legacy direct manipulation APIs (for `ReactNativeElement`).
|
||||
|
||||
void NativeDOM::setNativeProps(
|
||||
jsi::Runtime& rt,
|
||||
jsi::Value nativeElementReference,
|
||||
jsi::Value updatePayload) {
|
||||
getUIManagerFromRuntime(rt).setNativeProps_DEPRECATED(
|
||||
shadowNodeFromValue(rt, nativeElementReference),
|
||||
RawProps(rt, updatePayload));
|
||||
}
|
||||
|
||||
} // namespace facebook::react
|
||||
|
||||
@@ -122,6 +122,13 @@ class NativeDOM : public NativeDOMCxxSpec<NativeDOM> {
|
||||
jsi::Value relativeToNativeElementReference,
|
||||
jsi::Function onFail,
|
||||
jsi::Function onSuccess);
|
||||
|
||||
#pragma mark - Legacy direct manipulation APIs (for `ReactNativeElement`).
|
||||
|
||||
void setNativeProps(
|
||||
jsi::Runtime& rt,
|
||||
jsi::Value nativeElementReference,
|
||||
jsi::Value updatePayload);
|
||||
};
|
||||
|
||||
} // namespace facebook::react
|
||||
|
||||
@@ -12,7 +12,6 @@
|
||||
|
||||
import type {
|
||||
InternalInstanceHandle,
|
||||
Node as ShadowNode,
|
||||
ViewConfig,
|
||||
} from '../../../../../Libraries/Renderer/shims/ReactNativeTypes';
|
||||
import type {
|
||||
@@ -26,7 +25,6 @@ import type {InstanceHandle} from './internals/NodeInternals';
|
||||
import type ReactNativeDocument from './ReactNativeDocument';
|
||||
|
||||
import TextInputState from '../../../../../Libraries/Components/TextInput/TextInputState';
|
||||
import {getFabricUIManager} from '../../../../../Libraries/ReactNative/FabricUIManager';
|
||||
import {create as createAttributePayload} from '../../../../../Libraries/ReactNative/ReactFabricPublicInstance/ReactNativeAttributePayload';
|
||||
import warnForStyleProps from '../../../../../Libraries/ReactNative/ReactFabricPublicInstance/warnForStyleProps';
|
||||
import {
|
||||
@@ -37,7 +35,6 @@ import {
|
||||
} from './internals/NodeInternals';
|
||||
import ReadOnlyElement, {getBoundingClientRect} from './ReadOnlyElement';
|
||||
import NativeDOM from './specs/NativeDOM';
|
||||
import nullthrows from 'nullthrows';
|
||||
|
||||
const noop = () => {};
|
||||
|
||||
@@ -205,12 +202,7 @@ class ReactNativeElement extends ReadOnlyElement implements NativeMethods {
|
||||
const node = getNativeElementReference(this);
|
||||
|
||||
if (node != null && updatePayload != null) {
|
||||
// $FlowExpectedError[incompatible-type] This is an element instance so the native node reference is always a shadow node.
|
||||
const shadowNode: ShadowNode = node;
|
||||
nullthrows(getFabricUIManager()).setNativeProps(
|
||||
shadowNode,
|
||||
updatePayload,
|
||||
);
|
||||
NativeDOM.setNativeProps(node, updatePayload);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,6 +13,7 @@ import type {Node as ShadowNode} from '../../../../../../Libraries/Renderer/shim
|
||||
import type {TurboModule} from '../../../../../../Libraries/TurboModule/RCTExport';
|
||||
import type {InstanceHandle} from '../internals/NodeInternals';
|
||||
|
||||
import {getFabricUIManager} from '../../../../../../Libraries/ReactNative/FabricUIManager';
|
||||
import * as TurboModuleRegistry from '../../../../../../Libraries/TurboModule/TurboModuleRegistry';
|
||||
import nullthrows from 'nullthrows';
|
||||
|
||||
@@ -154,10 +155,23 @@ export interface Spec extends TurboModule {
|
||||
onFail: () => void,
|
||||
onSuccess: MeasureLayoutOnSuccessCallback,
|
||||
) => void;
|
||||
|
||||
/**
|
||||
* Legacy direct manipulation APIs (for `ReactNativeElement`).
|
||||
*/
|
||||
|
||||
+setNativeProps?: (
|
||||
nativeElementReference: mixed,
|
||||
updatePayload: mixed,
|
||||
) => void;
|
||||
}
|
||||
|
||||
const RawNativeDOM = (TurboModuleRegistry.get<Spec>('NativeDOMCxx'): ?Spec);
|
||||
|
||||
export function getRawNativeDOMForTests(): ?Spec {
|
||||
return RawNativeDOM;
|
||||
}
|
||||
|
||||
// This is the actual interface of this module, but the native module codegen
|
||||
// isn't expressive enough yet.
|
||||
export interface RefinedSpec {
|
||||
@@ -408,6 +422,14 @@ export interface RefinedSpec {
|
||||
onFail: () => void,
|
||||
onSuccess: MeasureLayoutOnSuccessCallback,
|
||||
) => void;
|
||||
|
||||
/**
|
||||
* Legacy direct manipulation APIs
|
||||
*/
|
||||
+setNativeProps: (
|
||||
nativeElementReference: NativeElementReference,
|
||||
updatePayload: {...},
|
||||
) => void;
|
||||
}
|
||||
|
||||
const NativeDOM: RefinedSpec = {
|
||||
@@ -574,6 +596,22 @@ const NativeDOM: RefinedSpec = {
|
||||
onSuccess,
|
||||
);
|
||||
},
|
||||
|
||||
/**
|
||||
* Legacy direct manipulation APIs
|
||||
*/
|
||||
setNativeProps(nativeNodeReference, updatePayload) {
|
||||
// TODO: remove when RawNativeDOM.setNativeProps is NOT nullable.
|
||||
if (RawNativeDOM?.setNativeProps == null) {
|
||||
nullthrows(getFabricUIManager()).setNativeProps(
|
||||
nativeNodeReference,
|
||||
updatePayload,
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
return RawNativeDOM.setNativeProps(nativeNodeReference, updatePayload);
|
||||
},
|
||||
};
|
||||
|
||||
export default NativeDOM;
|
||||
|
||||
Reference in New Issue
Block a user