Repository navigation
Description
Description
Problem
Starting in version 0.74.1 and above, due to this change, the batchRenderingUpdatesInEventLoop feature flag is turned ON. This causes NativeCommands called in ref functions to fail.
<RTNCenteredText
{...props}
ref={element => {
if (element) {
Commands.trigger(element); // <-- trigger will not be called natively if batchRenderingUpdatesInEventLoop is turned ON
}
}}
/>
The corresponding NativeCommand:
// RTNCenteredText.mm
- (void)trigger {
NSLog(@"*** Fabric component trigger method called directly");
}
- (void)handleCommand:(const NSString *)commandName args:(const NSArray *)args {
NSString *TRIGGER = @"trigger";
if([commandName isEqual:TRIGGER]) {
[self trigger];
}
}
Diagnosis
The NativeCommand trigger fails because when synchronouslyDispatchCommandOnUIThread gets called, findComponentViewWithTag returns nil because the _registry does not contain the element.
When batchRenderingUpdatesInEventLoop is off, the _registry is correctly populated with all elements on the screen, and the NativeCommand trigger functions correctly.
If Commands.trigger is wrapped in a setTimeout, it gets called successfully.
<RTNCenteredText
{...props}
ref={element => {
if (element) {
setTimeout(() => {
Commands.trigger(element); // <-- trigger gets called successfully
}, 0);
}
}}
/>
Steps to reproduce
See the reproducer provided.
- Use
codegenNativeComponentandcodegenNativeCommandsto create aNativeCommand - Call the created
NativeCommandin areffunction - See that the
NativeCommanddoes NOT get called in versions>=0.74.1
React Native Version
0.74.5
Affected Platforms
Runtime - iOS
Areas
JSI - Javascript Interface, Bridgeless - The New Initialization Flow
Output of npx react-native info
N/A
Stacktrace or Logs
N/A
Reproducer
https://github.com/RyanCommits/RN74-issue-reproducer
Screenshots and Videos
No response
Activity
react-native-bot commentedon Sep 4, 2024
react-native-bot commentedon Sep 4, 2024
RyanCommits commentedon Sep 4, 2024
Upgraded reproducer to
0.74.5elencho commentedon Sep 17, 2024
@cortinico can I work on this?
cortinico commentedon Sep 17, 2024
@elencho feel free to investigate further.
Context from @rubennorte:
RyanCommits commentedon Oct 28, 2024
Our library is dependent on the immediate firing of
Commandsin the componentref.As we wait for this change, what would you @cortinico suggest as a workaround for now on this race condition? Is using
requestAnimationFrameto wrapCommandsa stable enough of a workaround for the view mutations to finish before the view commands fire?rubennorte commentedon Oct 29, 2024
requestAnimationFrameis essentiallysetTimeout(callback, 0)at the moment, so it's not really helpful for this.I'm not familiar with your use case, so it's hard to suggest a workaround. Maybe you can queue those commands in native instead?
RyanCommits commentedon Oct 29, 2024
At Fullstory we use method swizzling to get React classes to call our
Commands.All of this is to allow us to read a custom prop in the native code like:
<View customProp="customValue">In new architecture, everything is strongly typed in C++, so this is our workaround to read
customPropvalues off of a component for our native code to process.We need to read these props on view creation, and since it's React Classes that we're calling
Commandson, I think to leverage a queue, we'd have to rely on React Native's internal implementation.rubennorte commentedon Oct 29, 2024
@RyanCommits oh, I see. Would it make sense to use custom components instead of the RN built-ins in that case? Maybe replace
Viewwith a custom implementation that handles those attributes properly?RyanCommits commentedon Oct 29, 2024
The idea is for our users to be able to plug and play - install our plugin with minimal code changes and be able to tag their components. We could build a custom component, but then our users will have to replace every component that requires this feature. We would also lose the ability to use our babel plugin to auto-tag components with identifying props, including components within other libraries.
rubennorte commentedon Nov 12, 2024
We'll track the fix for this in #47576.
rubennorte commentedon Jan 31, 2025
Fixed in #47604