Skip to content

Commit 498069c

Browse files
authored
[RN][Doc] Add documentation on how to initialize and invalidate native modules (facebook#4565)
1 parent 91dab07 commit 498069c

File tree

3 files changed

+91
-2
lines changed

3 files changed

+91
-2
lines changed

docs/the-new-architecture/advanced-topics-modules.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,4 +7,4 @@ This guide will cover the following topics:
77
- [Add custom C++ types to your C++ modules](/docs/the-new-architecture/custom-cxx-types)
88
- [Use Swift in your Module](/docs/next/the-new-architecture/turbo-modules-with-swift)
99
- [Emit custom events from your Native Modules](/docs/next/the-new-architecture/native-modules-custom-events)
10-
<!-- - [Native Modules Lifecycle](/docs/next/the-new-architecture/native-modules-lifecycle) -->
10+
- [Native Modules Lifecycle](/docs/next/the-new-architecture/native-modules-lifecycle)

docs/the-new-architecture/native-modules-custom-events.md

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,6 @@ BUILD SUCCESSFUL in 837ms
101101
```
102102

103103
This is automatically run when you build your Android application.
104-
105104
</TabItem>
106105
<TabItem value="ios" label="iOS">
107106
Codegen is run as part of the script phases that's automatically added to the project generated by CocoaPods.
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
import Tabs from '@theme/Tabs'; import TabItem from '@theme/TabItem'; import constants from '@site/core/TabsConstants';
2+
3+
# Native Modules Lifecycle
4+
5+
In React Native, Native Modules are singleton. The Native Module infrastructure lazily creates a Native Modules the first time it is accessed and it keeps it around whenever the app requires it. This is a performance optimization that allows us to avoid the overhead of creating Native Modules eagerly, at app start, and it ensure faster startup times.
6+
7+
In a pure React Native app, the Native Modules are created once and they are never destroyed. However, in more complex apps, there might be use cases where the Native Modules are destroyed and recreated. Imagine, for example, a brownfield app that mixes some native views with some React Native surfaces, as presented in the [Integrating with Existing App guide](/docs/integration-with-existing-apps). In that case it might make sense to destroy a React Native instance when the user navigates away from a React Native surface and recreate it when the user navigates back to that surface.
8+
9+
When this happens, Native Module that are stateless won't cause any issues. However, for stateful Native Modules it might be necessary to properly invalidate the Native Module to ensure that the state is reset and the resources released.
10+
11+
In this guide, you will explore how to initialize and invalidate a Native Module properly. This guide assumes that you are familiar with how to write a Native Modules and you are comfortable writing native code. If you are not familiar with Native Modules, please read the [Native Modules guide](/docs/next/turbo-native-modules-introduction) first.
12+
13+
## Android
14+
15+
When it comes to Android, all the Native Modules already implements a [TurboModule](https://github.com/facebook/react-native/blob/main/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/turbomodule/core/interfaces/TurboModule.kt) interface that defines two methods: `initialize()` and `invalidate()`.
16+
17+
The `initialize()` method is called by the Native Module infrastructure when the Native Module is created. This is the best place to put all the initialization code that needs access to the ReactApplicationContext, for example. These are some Native Modules from core that implements the `initialize()` method: [BlobModule](https://github.com/facebook/react-native/blob/0617accecdcb11159ba15c34885f294bc206aa89/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/modules/blob/BlobModule.java#L155-L157), [NetworkingModule](https://github.com/facebook/react-native/blob/0617accecdcb11159ba15c34885f294bc206aa89/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/modules/network/NetworkingModule.java#L193-L197).
18+
19+
The `invalidate()` method is called by the Native Module infrastructure when the Native Module is destroyed. This is the best place to put all the cleanup code, resetting the Native Module state and release resources that are no longer needed, such as memory and files. These are some Native Modules from core that implements the `invalidate()` method: [DeviceInfoModule](https://github.com/facebook/react-native/blob/0617accecdcb11159ba15c34885f294bc206aa89/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/modules/deviceinfo/DeviceInfoModule.kt#L72-L76), [NetworkModule](https://github.com/facebook/react-native/blob/0617accecdcb11159ba15c34885f294bc206aa89/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/modules/network/NetworkingModule.java#L200-L212)
20+
21+
## iOS
22+
23+
On iOS, Native Modules conforms to the [`RCTTurboModule`](https://github.com/facebook/react-native/blob/0617accecdcb11159ba15c34885f294bc206aa89/packages/react-native/ReactCommon/react/nativemodule/core/platform/ios/ReactCommon/RCTTurboModule.h#L196-L200) protocol. However, this protocol does not expose the `initialize` and `invalidate` method that are exposed by the Android's `TurboModule` class.
24+
25+
Instead, on iOS, there are two additional protocols: [`RCTInitializing`](https://github.com/facebook/react-native/blob/0617accecdcb11159ba15c34885f294bc206aa89/packages/react-native/React/Base/RCTInitializing.h) and [`RCTInvalidating`](https://github.com/facebook/react-native/blob/0617accecdcb11159ba15c34885f294bc206aa89/packages/react-native/React/Base/RCTInvalidating.h). These protocols are used to define the `initialize` and `invalidate` methods, respectively.
26+
27+
If your module needs to run some initialization code, then you can conform to the `RCTInitializing` protocol and implement the `initialize` method. To do so, you have to:
28+
29+
1. Moduify the `NativeModule.h` file by adding the following lines:
30+
31+
```diff title="NativeModule.h"
32+
+ #import <React/RCTInitializing.h>
33+
34+
//...
35+
36+
- @interface NativeModule : NSObject <NativeModuleSpec>
37+
+ @interface NativeModule : NSObject <NativeModuleSpec, RCTInitializing>
38+
//...
39+
@end
40+
```
41+
42+
2. Implement the `initialize` method in the `NativeModule.mm` file:
43+
44+
```diff title="NativeModule.mm"
45+
// ...
46+
47+
@implementation NativeModule
48+
49+
+- (void)initialize {
50+
+ // add the initialization code here
51+
+}
52+
53+
@end
54+
```
55+
56+
These are some Native Modules from core that implements the `initialize` method: [RCTBlobManager](https://github.com/facebook/react-native/blob/0617accecdcb11159ba15c34885f294bc206aa89/packages/react-native/Libraries/Blob/RCTBlobManager.mm#L58-L68), [RCTTiming](https://github.com/facebook/react-native/blob/0617accecdcb11159ba15c34885f294bc206aa89/packages/react-native/React/CoreModules/RCTTiming.mm#L121-L124).
57+
58+
If your module needs to run some cleanup code, then you can conform to the `RCTInvalidating` protocol and implement the `invalidate` method. To do so, you have to:
59+
60+
1. Moduify the `NativeModule.h` file by adding the following lines:
61+
62+
```diff title="NativeModule.h"
63+
+ #import <React/RCTInvalidating.h>
64+
65+
//...
66+
67+
- @interface NativeModule : NSObject <NativeModuleSpec>
68+
+ @interface NativeModule : NSObject <NativeModuleSpec, RCTInvalidating>
69+
70+
//...
71+
72+
@end
73+
```
74+
75+
2. Implement the `invalidate` method in the `NativeModule.mm` file:
76+
77+
```diff title="NativeModule.mm"
78+
79+
// ...
80+
81+
@implementation NativeModule
82+
83+
+- (void)invalidate {
84+
+ // add the cleanup code here
85+
+}
86+
87+
@end
88+
```
89+
90+
These are some Native Modules from core that implements the `invalidate` method: [RCTAppearance](https://github.com/facebook/react-native/blob/0617accecdcb11159ba15c34885f294bc206aa89/packages/react-native/React/CoreModules/RCTAppearance.mm#L151-L155), [RCTDeviceInfo](https://github.com/facebook/react-native/blob/0617accecdcb11159ba15c34885f294bc206aa89/packages/react-native/React/CoreModules/RCTDeviceInfo.mm#L127-L133).

0 commit comments

Comments
 (0)