RN 0.74 Bridgeless support
Description
This PR adds support of new stable Bridgeless mode and partial migration from deprecated components. Still need some additional work to make iOS work, but all major issues was resolved with two first commits. To get this work properly, we need to wait this changes in next RN release, that's why RNN bridgeless will only work with RN 0.74.2 and higher (This changes are from Expo team cause they also need such functionality).
What was done
Common:
- Migrated to Yarn3 (following RN)
- Added codegen for TurboModules API
- Turbomodules for
RNNEventEmitterandRNNCommandsModule - JS CommandsModule architecture-independent implementation (transforms sync to async Turbomodule call if using legacy methods, this should help to update library in production app without any JS changes)
iOS:
- waitForRender is YES by default for new architecture
- File structure now separates files by purpose (this helps separate RN-dependent components from independent abstractions)
- Migration to C++20
- Migration to ObjectiveC++
-
RNNEventEmitteris a base class now.RNNBridgeEventEmitterandRNNTurboEventEmitterare children of this class -
RNNReactViewwas migrated toRCTSurfaceHostingView(in new architecture mode) -
RNNAppDelegatenow extendsRCTAppDelegate -
RNNAppDelegatenow usesRCTRootViewFactoryandRCTHostinstead ofRCTBridge(In new architecture mode with bridgeless support) - Added
RNNTurboCommandsHandleras proxy forRNNCommandsHandler - Added
ReactNativeNavigation:bootstrapWithHost:for bridgeless mode - Added conditional
RCTHost(bridgeless) support for almost all core classes (need some work for SurfaceAnimationController), guarded by preprocessors:
#ifdef RCT_NEW_ARCH_ENABLED // new architecture branch
if (_host != nil) {
[_host callSomething]; // bridgeless mode
} else {
[_bridge callSomething]; // bridge support
}
#else // old architecture branch
[_bridge callSomething];
#endif
TODO
Common:
- [ ] Add detailed description
- [ ] Prettify code
- [x] [Playground] Remove libs that does not support Bridgeless
- [x] [Playground] Migrate to Reanimated v3 to support Bridgeless
iOS:
- [x] Bridgeless mode with bridge support for both old and new architectures
- [ ] LeakChecker warnings in some flows
- [ ] [New Architecture] find element by ID for shared element transition without UIManager
- [ ] [New Architecture] setRoot failure cause of recursive invalidate call in RCTSurfaceHostingView instance
- [ ] [Bridgeless] use RCTHost -> DidReceiveReloadCommand in RNNTurboModuleManager instead of bridge events
- [ ] [Bridgeless] Test SurfaceAnimationController -> observer with RCTHost instead of _bridge.uiManager
Android:
- [ ] Bridgeless mode with bridge support for both old and new architectures
🚀
Thanks for a great PR! But could you please check one more thing: what happens if Navigation.setRoot is called once again? (for example, when any button on the root screen calls this method)
@Arkkeeper sure, I'll check this, but it could be a bit buggy (PR is still a draft/PoC, im planning to finish with iOS next week and start android), hope to resolve all the issues
There is an interesting moment regarding new architecture: RCTEventEmitter fires 'didApper' event before component actually was created (event JS component class constructor was not been called yet).
Native call is triggered by viewDidApper lifecycle iOS event when native navigator is ready, but react view is still not, that's why after loading of react view we are getting correct view, but no event about appear status.
I think it's because of synchronous nature of new architecture, cause with old architecture we sending events from native before first render, but they emitted in JS only after render. Workaround - waitForRender: true by default with Fabric/New Architecture, but it could be reverted by setting navigation options.
iOS example app now works fine for both old and new archs (with and without bridge) 🎉
Working on ToDo list right now
After porting SharedElementTransition example to Reanimated 3 (to support bridgeless), i found that new Reaniamted does not support multiple surfaces yet (one native screen - one surface)
To fix this locally, we actually need to change assertion to if branch and return nullptr as result of commit lambda
Looking forward to this one 🎉🎉
@TheLonelyAstronaut can you share an update on your progress?
Bump, looking forward for this.
@TheLonelyAstronaut Hi, any progress ? If you are busy, can you describe what is left to be done, I could take over. Thanks :)
@lukutism Hi, no progress yet, i have very complex task on my job right now. You could start Android implementation, I did only iOS things