Skip to content

Commit 0dbe206

Browse files
committed
Create 0000-enhanced-lifecycle-aware-module-registry.md
1 parent 7b3286f commit 0dbe206

File tree

1 file changed

+187
-0
lines changed

1 file changed

+187
-0
lines changed
Lines changed: 187 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,187 @@
1+
---
2+
title: Enhanced lifecycle-aware module registry
3+
author:
4+
- Matin Zadeh Dolatabad
5+
date: 2025-01-06
6+
---
7+
8+
# RFC0000: Enhanced lifecycle-aware module registry
9+
10+
## Summary
11+
12+
This RFC proposes a framework to enhance the module registry in React Native by introducing a lifecycle-aware system for native modules. The goal is to address the current gap in handling application lifecycle events, akin to Flutter's `FlutterPlugin` and `FlutterApplicationLifeCycleDelegate`. The design enables seamless integration of native modules with application lifecycle events across iOS and Android platforms. There is also Expo Modules Core that handles this, but React Native does not have this by default and it requires Expo to be used in such cases.
13+
14+
## Motivation
15+
16+
React Native lacks a comprehensive and standardized approach for native module lifecycle management. Unlike Flutter, where plugins can hook into application lifecycle events via a well-defined protocol, React Native requires developers to implement custom solutions for such behavior. This limitation results in increased boilerplate code, fragmented implementations, and an inconsistent developer experience.
17+
18+
### Key Challenges Addressed:
19+
20+
- **Limited Module Registry:** React Native's module registry doesn't natively support lifecycle awareness. On Android, React Native provides a `LifecycleEventListener` that partially addresses this by allowing modules to listen to events like `onHostResume`, `onHostPause`, and `onHostDestroy`. However, there is no support for early lifecycle events such as `onCreate` or `onTerminate`. On iOS, there is no equivalent lifecycle support, leading to significant gaps in managing the full application lifecycle effectively across platforms.
21+
- **Manual Lifecycle Handling:** Developers must manually wire up lifecycle events for each native module.
22+
- **Inconsistency Across Platforms:** There is no unified approach for managing lifecycle events across iOS and Android except `Expo Modules API`.
23+
24+
## Detailed Design
25+
26+
The proposed solution introduces a `LifecycleAwareModule` interface and a centralized lifecycle manager for React Native. This framework would:
27+
28+
1. Allow native modules to register as lifecycle-aware.
29+
2. Notify registered modules of key application lifecycle events.
30+
3. Provide a consistent API across platforms.
31+
32+
### iOS Implementation
33+
34+
Define a protocol for lifecycle-aware modules:
35+
36+
```objc
37+
@protocol RNLifecycleAwareModule <NSObject>
38+
@optional
39+
- (void)applicationDidFinishLaunching:(UIApplication *)application;
40+
- (void)applicationWillResignActive:(UIApplication *)application;
41+
- (void)applicationDidEnterBackground:(UIApplication *)application;
42+
- (void)applicationWillEnterForeground:(UIApplication *)application;
43+
- (void)applicationDidBecomeActive:(UIApplication *)application;
44+
- (void)applicationWillTerminate:(UIApplication *)application;
45+
@end
46+
```
47+
48+
Create a `RNLifecycleManager` to manage registered modules:
49+
50+
```objc
51+
@interface RNLifecycleManager : NSObject
52+
+ (instancetype)sharedInstance;
53+
- (void)registerModule:(id<RNLifecycleAwareModule>)module;
54+
- (void)notifyModulesWithSelector:(SEL)selector application:(UIApplication *)application;
55+
@end
56+
```
57+
58+
Hook into `AppDelegate`:
59+
60+
```objc
61+
@implementation AppDelegate
62+
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
63+
[[RNLifecycleManager sharedInstance] notifyModulesWithSelector:@selector(applicationDidFinishLaunching:) application:application];
64+
return YES;
65+
}
66+
@end
67+
```
68+
69+
### Android Implementation
70+
71+
Define an interface for lifecycle-aware modules:
72+
73+
```kotlin
74+
interface RNLifecycleAwareModule {
75+
fun onCreate(application: Application)
76+
fun onResume()
77+
fun onPause()
78+
fun onStop()
79+
fun onDestroy()
80+
}
81+
```
82+
83+
Create a `LifecycleManager` to manage registered modules:
84+
85+
```kotlin
86+
object LifecycleManager {
87+
private val modules = mutableListOf<RNLifecycleAwareModule>()
88+
89+
fun registerModule(module: RNLifecycleAwareModule) {
90+
modules.add(module)
91+
}
92+
93+
fun notify(event: (RNLifecycleAwareModule) -> Unit) {
94+
modules.forEach { event(it) }
95+
}
96+
}
97+
```
98+
99+
Hook into `Application`:
100+
101+
```kotlin
102+
class MainApplication : Application() {
103+
override fun onCreate() {
104+
super.onCreate()
105+
LifecycleManager.notify { it.onCreate(this) }
106+
}
107+
108+
override fun onTerminate() {
109+
super.onTerminate()
110+
LifecycleManager.notify { it.onDestroy() }
111+
}
112+
}
113+
```
114+
115+
### Usage Inside Libraries
116+
117+
Libraries can leverage the lifecycle-aware module registry to handle lifecycle events seamlessly. For instance:
118+
119+
#### iOS Example
120+
121+
```objc
122+
@interface MyModule : NSObject <RNLifecycleAwareModule>
123+
@end
124+
125+
@implementation MyModule
126+
127+
- (void)applicationDidFinishLaunching:(UIApplication *)application {
128+
// Initialize resources
129+
}
130+
131+
- (void)applicationDidEnterBackground:(UIApplication *)application {
132+
// Save state
133+
}
134+
135+
@end
136+
```
137+
138+
#### Android Example
139+
140+
```kotlin
141+
class MyModule : RNLifecycleAwareModule {
142+
override fun onCreate(application: Application) {
143+
// Initialize resources
144+
}
145+
146+
override fun onPause() {
147+
// Save state
148+
}
149+
}
150+
```
151+
152+
By implementing the `RNLifecycleAwareModule` interface, library developers can ensure that their modules respond appropriately to lifecycle events without requiring additional setup from the application developers.
153+
154+
However the design details here are just a demonstration and the actual implementation may vary. This implementation ca be baked into the current interface or a new interface can be introduced.
155+
156+
## Drawbacks
157+
158+
- **Backward Compatibility:** Existing modules will need updates to implement the lifecycle-aware interface.
159+
- **Performance Overhead:** Centralized lifecycle management may introduce performance overhead, especially with many registered modules.
160+
- **Potential Conflicts:** Modules that handle lifecycle events internally may conflict with the centralized lifecycle manager.
161+
162+
## Alternatives
163+
164+
### Option 1
165+
166+
Use third-party libraries for lifecycle management, but this lacks standardization and official support.
167+
168+
### Option 2
169+
170+
Continue with the current approach, leaving lifecycle management to individual frameworks/developers.
171+
172+
## Adoption Strategy
173+
174+
- Introduce as an optional feature in a minor React Native release.
175+
- Provide detailed documentation and examples.
176+
- Encourage library authors to adopt the lifecycle-aware interface for their modules.
177+
178+
## How We Teach This
179+
180+
- Update official documentation with lifecycle-aware module examples.
181+
- Provide tutorials and migration guides for developers.
182+
- Offer webinars or workshops to explain the new system.
183+
184+
## Unresolved Questions
185+
186+
- How to handle potential performance overhead with many registered modules?
187+
- How to ensure compatibility with existing React Native libraries?

0 commit comments

Comments
 (0)