diff --git a/archived_docs/version-0.44/integration-with-existing-apps.md b/archived_docs/version-0.44/integration-with-existing-apps.md
index 3b8b645d94c..19e3438333a 100644
--- a/archived_docs/version-0.44/integration-with-existing-apps.md
+++ b/archived_docs/version-0.44/integration-with-existing-apps.md
@@ -393,7 +393,7 @@ We will, for debugging purposes, log that the event handler was invoked. Then, w
}
```
-> Note that `RCTRootView initWithURL` starts up a new JSC VM. To save resources and simplify the communication between RN views in different parts of your native app, you can have multiple views powered by React Native that are associated with a single JS runtime. To do that, instead of using `[RCTRootView alloc] initWithURL`, use [`RCTBridge initWithBundleURL`](https://github.com/facebook/react-native/blob/master/React/Base/RCTBridge.h#L93) to create a bridge and then use `RCTRootView initWithBridge`.
+> Note that `RCTRootView initWithBundleURL` starts up a new JSC VM. To save resources and simplify the communication between RN views in different parts of your native app, you can have multiple views powered by React Native that are associated with a single JS runtime. To do that, instead of using `[RCTRootView alloc] initWithBundleURL`, use [`RCTBridge initWithBundleURL`](https://github.com/facebook/react-native/blob/master/React/Base/RCTBridge.h#L93) to create a bridge and then use `RCTRootView initWithBridge`.
diff --git a/archived_docs/version-0.45/integration-with-existing-apps.md b/archived_docs/version-0.45/integration-with-existing-apps.md
index 6fd8e07d1a2..1a909e8127a 100644
--- a/archived_docs/version-0.45/integration-with-existing-apps.md
+++ b/archived_docs/version-0.45/integration-with-existing-apps.md
@@ -393,7 +393,7 @@ We will, for debugging purposes, log that the event handler was invoked. Then, w
}
```
-> Note that `RCTRootView initWithURL` starts up a new JSC VM. To save resources and simplify the communication between RN views in different parts of your native app, you can have multiple views powered by React Native that are associated with a single JS runtime. To do that, instead of using `[RCTRootView alloc] initWithURL`, use [`RCTBridge initWithBundleURL`](https://github.com/facebook/react-native/blob/master/React/Base/RCTBridge.h#L93) to create a bridge and then use `RCTRootView initWithBridge`.
+> Note that `RCTRootView initWithBundleURL` starts up a new JSC VM. To save resources and simplify the communication between RN views in different parts of your native app, you can have multiple views powered by React Native that are associated with a single JS runtime. To do that, instead of using `[RCTRootView alloc] initWithBundleURL`, use [`RCTBridge initWithBundleURL`](https://github.com/facebook/react-native/blob/master/React/Base/RCTBridge.h#L93) to create a bridge and then use `RCTRootView initWithBridge`.
diff --git a/archived_docs/version-0.46/integration-with-existing-apps.md b/archived_docs/version-0.46/integration-with-existing-apps.md
index b9255494bdf..bf347ce7abd 100644
--- a/archived_docs/version-0.46/integration-with-existing-apps.md
+++ b/archived_docs/version-0.46/integration-with-existing-apps.md
@@ -393,7 +393,7 @@ We will, for debugging purposes, log that the event handler was invoked. Then, w
}
```
-> Note that `RCTRootView initWithURL` starts up a new JSC VM. To save resources and simplify the communication between RN views in different parts of your native app, you can have multiple views powered by React Native that are associated with a single JS runtime. To do that, instead of using `[RCTRootView alloc] initWithURL`, use [`RCTBridge initWithBundleURL`](https://github.com/facebook/react-native/blob/master/React/Base/RCTBridge.h#L93) to create a bridge and then use `RCTRootView initWithBridge`.
+> Note that `RCTRootView initWithBundleURL` starts up a new JSC VM. To save resources and simplify the communication between RN views in different parts of your native app, you can have multiple views powered by React Native that are associated with a single JS runtime. To do that, instead of using `[RCTRootView alloc] initWithBundleURL`, use [`RCTBridge initWithBundleURL`](https://github.com/facebook/react-native/blob/master/React/Base/RCTBridge.h#L93) to create a bridge and then use `RCTRootView initWithBridge`.
diff --git a/archived_docs/version-0.47/integration-with-existing-apps.md b/archived_docs/version-0.47/integration-with-existing-apps.md
index 5cc91d0a458..c9a48ccbca0 100644
--- a/archived_docs/version-0.47/integration-with-existing-apps.md
+++ b/archived_docs/version-0.47/integration-with-existing-apps.md
@@ -393,7 +393,7 @@ We will, for debugging purposes, log that the event handler was invoked. Then, w
}
```
-> Note that `RCTRootView initWithURL` starts up a new JSC VM. To save resources and simplify the communication between RN views in different parts of your native app, you can have multiple views powered by React Native that are associated with a single JS runtime. To do that, instead of using `[RCTRootView alloc] initWithURL`, use [`RCTBridge initWithBundleURL`](https://github.com/facebook/react-native/blob/master/React/Base/RCTBridge.h#L93) to create a bridge and then use `RCTRootView initWithBridge`.
+> Note that `RCTRootView initWithBundleURL` starts up a new JSC VM. To save resources and simplify the communication between RN views in different parts of your native app, you can have multiple views powered by React Native that are associated with a single JS runtime. To do that, instead of using `[RCTRootView alloc] initWithBundleURL`, use [`RCTBridge initWithBundleURL`](https://github.com/facebook/react-native/blob/master/React/Base/RCTBridge.h#L93) to create a bridge and then use `RCTRootView initWithBridge`.
diff --git a/archived_docs/version-0.48/integration-with-existing-apps.md b/archived_docs/version-0.48/integration-with-existing-apps.md
index d6a8fb3e982..c193d428b5f 100644
--- a/archived_docs/version-0.48/integration-with-existing-apps.md
+++ b/archived_docs/version-0.48/integration-with-existing-apps.md
@@ -393,7 +393,7 @@ We will, for debugging purposes, log that the event handler was invoked. Then, w
}
```
-> Note that `RCTRootView initWithURL` starts up a new JSC VM. To save resources and simplify the communication between RN views in different parts of your native app, you can have multiple views powered by React Native that are associated with a single JS runtime. To do that, instead of using `[RCTRootView alloc] initWithURL`, use [`RCTBridge initWithBundleURL`](https://github.com/facebook/react-native/blob/master/React/Base/RCTBridge.h#L93) to create a bridge and then use `RCTRootView initWithBridge`.
+> Note that `RCTRootView initWithBundleURL` starts up a new JSC VM. To save resources and simplify the communication between RN views in different parts of your native app, you can have multiple views powered by React Native that are associated with a single JS runtime. To do that, instead of using `[RCTRootView alloc] initWithBundleURL`, use [`RCTBridge initWithBundleURL`](https://github.com/facebook/react-native/blob/master/React/Base/RCTBridge.h#L93) to create a bridge and then use `RCTRootView initWithBridge`.
diff --git a/archived_docs/version-0.49/integration-with-existing-apps.md b/archived_docs/version-0.49/integration-with-existing-apps.md
index 4c6ca00afd6..fab0d73c673 100644
--- a/archived_docs/version-0.49/integration-with-existing-apps.md
+++ b/archived_docs/version-0.49/integration-with-existing-apps.md
@@ -391,7 +391,7 @@ We will, for debugging purposes, log that the event handler was invoked. Then, w
}
```
-> Note that `RCTRootView initWithURL` starts up a new JSC VM. To save resources and simplify the communication between RN views in different parts of your native app, you can have multiple views powered by React Native that are associated with a single JS runtime. To do that, instead of using `[RCTRootView alloc] initWithURL`, use [`RCTBridge initWithBundleURL`](https://github.com/facebook/react-native/blob/master/React/Base/RCTBridge.h#L93) to create a bridge and then use `RCTRootView initWithBridge`.
+> Note that `RCTRootView initWithBundleURL` starts up a new JSC VM. To save resources and simplify the communication between RN views in different parts of your native app, you can have multiple views powered by React Native that are associated with a single JS runtime. To do that, instead of using `[RCTRootView alloc] initWithBundleURL`, use [`RCTBridge initWithBundleURL`](https://github.com/facebook/react-native/blob/master/React/Base/RCTBridge.h#L93) to create a bridge and then use `RCTRootView initWithBridge`.
diff --git a/archived_docs/version-0.50/integration-with-existing-apps.md b/archived_docs/version-0.50/integration-with-existing-apps.md
index 42fb19ff91f..3a99f51d656 100644
--- a/archived_docs/version-0.50/integration-with-existing-apps.md
+++ b/archived_docs/version-0.50/integration-with-existing-apps.md
@@ -402,7 +402,7 @@ We will, for debugging purposes, log that the event handler was invoked. Then, w
}
```
-> Note that `RCTRootView initWithURL` starts up a new JSC VM. To save resources and simplify the communication between RN views in different parts of your native app, you can have multiple views powered by React Native that are associated with a single JS runtime. To do that, instead of using `[RCTRootView alloc] initWithURL`, use [`RCTBridge initWithBundleURL`](https://github.com/facebook/react-native/blob/master/React/Base/RCTBridge.h#L93) to create a bridge and then use `RCTRootView initWithBridge`.
+> Note that `RCTRootView initWithBundleURL` starts up a new JSC VM. To save resources and simplify the communication between RN views in different parts of your native app, you can have multiple views powered by React Native that are associated with a single JS runtime. To do that, instead of using `[RCTRootView alloc] initWithBundleURL`, use [`RCTBridge initWithBundleURL`](https://github.com/facebook/react-native/blob/master/React/Base/RCTBridge.h#L93) to create a bridge and then use `RCTRootView initWithBridge`.
diff --git a/archived_docs/version-0.51/integration-with-existing-apps.md b/archived_docs/version-0.51/integration-with-existing-apps.md
index c379594bae9..77412b65686 100644
--- a/archived_docs/version-0.51/integration-with-existing-apps.md
+++ b/archived_docs/version-0.51/integration-with-existing-apps.md
@@ -402,7 +402,7 @@ We will, for debugging purposes, log that the event handler was invoked. Then, w
}
```
-> Note that `RCTRootView initWithURL` starts up a new JSC VM. To save resources and simplify the communication between RN views in different parts of your native app, you can have multiple views powered by React Native that are associated with a single JS runtime. To do that, instead of using `[RCTRootView alloc] initWithURL`, use [`RCTBridge initWithBundleURL`](https://github.com/facebook/react-native/blob/master/React/Base/RCTBridge.h#L93) to create a bridge and then use `RCTRootView initWithBridge`.
+> Note that `RCTRootView initWithBundleURL` starts up a new JSC VM. To save resources and simplify the communication between RN views in different parts of your native app, you can have multiple views powered by React Native that are associated with a single JS runtime. To do that, instead of using `[RCTRootView alloc] initWithBundleURL`, use [`RCTBridge initWithBundleURL`](https://github.com/facebook/react-native/blob/master/React/Base/RCTBridge.h#L93) to create a bridge and then use `RCTRootView initWithBridge`.
diff --git a/archived_docs/version-0.55/integration-with-existing-apps.md b/archived_docs/version-0.55/integration-with-existing-apps.md
index 9114a11a39d..3e8fa2f0a97 100644
--- a/archived_docs/version-0.55/integration-with-existing-apps.md
+++ b/archived_docs/version-0.55/integration-with-existing-apps.md
@@ -380,7 +380,7 @@ We will, for debugging purposes, log that the event handler was invoked. Then, w
}
```
-> Note that `RCTRootView initWithURL` starts up a new JSC VM. To save resources and simplify the communication between RN views in different parts of your native app, you can have multiple views powered by React Native that are associated with a single JS runtime. To do that, instead of using `[RCTRootView alloc] initWithURL`, use [`RCTBridge initWithBundleURL`](https://github.com/facebook/react-native/blob/master/React/Base/RCTBridge.h#L93) to create a bridge and then use `RCTRootView initWithBridge`.
+> Note that `RCTRootView initWithBundleURL` starts up a new JSC VM. To save resources and simplify the communication between RN views in different parts of your native app, you can have multiple views powered by React Native that are associated with a single JS runtime. To do that, instead of using `[RCTRootView alloc] initWithBundleURL`, use [`RCTBridge initWithBundleURL`](https://github.com/facebook/react-native/blob/master/React/Base/RCTBridge.h#L93) to create a bridge and then use `RCTRootView initWithBridge`.
diff --git a/archived_docs/version-0.56/integration-with-existing-apps.md b/archived_docs/version-0.56/integration-with-existing-apps.md
index 63996a5ac27..2db4453b2be 100644
--- a/archived_docs/version-0.56/integration-with-existing-apps.md
+++ b/archived_docs/version-0.56/integration-with-existing-apps.md
@@ -380,7 +380,7 @@ We will, for debugging purposes, log that the event handler was invoked. Then, w
}
```
-> Note that `RCTRootView initWithURL` starts up a new JSC VM. To save resources and simplify the communication between RN views in different parts of your native app, you can have multiple views powered by React Native that are associated with a single JS runtime. To do that, instead of using `[RCTRootView alloc] initWithURL`, use [`RCTBridge initWithBundleURL`](https://github.com/facebook/react-native/blob/master/React/Base/RCTBridge.h#L93) to create a bridge and then use `RCTRootView initWithBridge`.
+> Note that `RCTRootView initWithBundleURL` starts up a new JSC VM. To save resources and simplify the communication between RN views in different parts of your native app, you can have multiple views powered by React Native that are associated with a single JS runtime. To do that, instead of using `[RCTRootView alloc] initWithBundleURL`, use [`RCTBridge initWithBundleURL`](https://github.com/facebook/react-native/blob/master/React/Base/RCTBridge.h#L93) to create a bridge and then use `RCTRootView initWithBridge`.
diff --git a/archived_docs/version-0.57/integration-with-existing-apps.md b/archived_docs/version-0.57/integration-with-existing-apps.md
index 96b7b580d82..d6abc241894 100644
--- a/archived_docs/version-0.57/integration-with-existing-apps.md
+++ b/archived_docs/version-0.57/integration-with-existing-apps.md
@@ -380,7 +380,7 @@ We will, for debugging purposes, log that the event handler was invoked. Then, w
}
```
-> Note that `RCTRootView initWithURL` starts up a new JSC VM. To save resources and simplify the communication between RN views in different parts of your native app, you can have multiple views powered by React Native that are associated with a single JS runtime. To do that, instead of using `[RCTRootView alloc] initWithURL`, use [`RCTBridge initWithBundleURL`](https://github.com/facebook/react-native/blob/master/React/Base/RCTBridge.h#L93) to create a bridge and then use `RCTRootView initWithBridge`.
+> Note that `RCTRootView initWithBundleURL` starts up a new JSC VM. To save resources and simplify the communication between RN views in different parts of your native app, you can have multiple views powered by React Native that are associated with a single JS runtime. To do that, instead of using `[RCTRootView alloc] initWithBundleURL`, use [`RCTBridge initWithBundleURL`](https://github.com/facebook/react-native/blob/master/React/Base/RCTBridge.h#L93) to create a bridge and then use `RCTRootView initWithBridge`.
diff --git a/archived_docs/version-0.58/integration-with-existing-apps.md b/archived_docs/version-0.58/integration-with-existing-apps.md
index f4908a6d330..ea6cd048fc1 100644
--- a/archived_docs/version-0.58/integration-with-existing-apps.md
+++ b/archived_docs/version-0.58/integration-with-existing-apps.md
@@ -380,7 +380,7 @@ We will, for debugging purposes, log that the event handler was invoked. Then, w
}
```
-> Note that `RCTRootView initWithURL` starts up a new JSC VM. To save resources and simplify the communication between RN views in different parts of your native app, you can have multiple views powered by React Native that are associated with a single JS runtime. To do that, instead of using `[RCTRootView alloc] initWithURL`, use [`RCTBridge initWithBundleURL`](https://github.com/facebook/react-native/blob/master/React/Base/RCTBridge.h#L93) to create a bridge and then use `RCTRootView initWithBridge`.
+> Note that `RCTRootView initWithBundleURL` starts up a new JSC VM. To save resources and simplify the communication between RN views in different parts of your native app, you can have multiple views powered by React Native that are associated with a single JS runtime. To do that, instead of using `[RCTRootView alloc] initWithBundleURL`, use [`RCTBridge initWithBundleURL`](https://github.com/facebook/react-native/blob/master/React/Base/RCTBridge.h#L93) to create a bridge and then use `RCTRootView initWithBridge`.
diff --git a/archived_docs/version-0.59/integration-with-existing-apps.md b/archived_docs/version-0.59/integration-with-existing-apps.md
index 107449bb5ed..4203582ae07 100644
--- a/archived_docs/version-0.59/integration-with-existing-apps.md
+++ b/archived_docs/version-0.59/integration-with-existing-apps.md
@@ -380,7 +380,7 @@ We will, for debugging purposes, log that the event handler was invoked. Then, w
}
```
-> Note that `RCTRootView initWithURL` starts up a new JSC VM. To save resources and simplify the communication between RN views in different parts of your native app, you can have multiple views powered by React Native that are associated with a single JS runtime. To do that, instead of using `[RCTRootView alloc] initWithURL`, use [`RCTBridge initWithBundleURL`](https://github.com/facebook/react-native/blob/master/React/Base/RCTBridge.h#L93) to create a bridge and then use `RCTRootView initWithBridge`.
+> Note that `RCTRootView initWithBundleURL` starts up a new JSC VM. To save resources and simplify the communication between RN views in different parts of your native app, you can have multiple views powered by React Native that are associated with a single JS runtime. To do that, instead of using `[RCTRootView alloc] initWithBundleURL`, use [`RCTBridge initWithBundleURL`](https://github.com/facebook/react-native/blob/master/React/Base/RCTBridge.h#L93) to create a bridge and then use `RCTRootView initWithBridge`.
diff --git a/archived_docs/version-0.60/integration-with-existing-apps.md b/archived_docs/version-0.60/integration-with-existing-apps.md
index 1dc47babf6c..98e7f0beb7b 100644
--- a/archived_docs/version-0.60/integration-with-existing-apps.md
+++ b/archived_docs/version-0.60/integration-with-existing-apps.md
@@ -396,7 +396,7 @@ We will, for debugging purposes, log that the event handler was invoked. Then, w
}
```
-> Note that `RCTRootView initWithURL` starts up a new JSC VM. To save resources and simplify the communication between RN views in different parts of your native app, you can have multiple views powered by React Native that are associated with a single JS runtime. To do that, instead of using `[RCTRootView alloc] initWithURL`, use [`RCTBridge initWithBundleURL`](https://github.com/facebook/react-native/blob/master/React/Base/RCTBridge.h#L93) to create a bridge and then use `RCTRootView initWithBridge`.
+> Note that `RCTRootView initWithBundleURL` starts up a new JSC VM. To save resources and simplify the communication between RN views in different parts of your native app, you can have multiple views powered by React Native that are associated with a single JS runtime. To do that, instead of using `[RCTRootView alloc] initWithBundleURL`, use [`RCTBridge initWithBundleURL`](https://github.com/facebook/react-native/blob/master/React/Base/RCTBridge.h#L93) to create a bridge and then use `RCTRootView initWithBridge`.
diff --git a/archived_docs/version-0.61/integration-with-existing-apps.md b/archived_docs/version-0.61/integration-with-existing-apps.md
index 3c0a0dfa9db..8c930a982ae 100644
--- a/archived_docs/version-0.61/integration-with-existing-apps.md
+++ b/archived_docs/version-0.61/integration-with-existing-apps.md
@@ -394,7 +394,7 @@ We will, for debugging purposes, log that the event handler was invoked. Then, w
}
```
-> Note that `RCTRootView initWithURL` starts up a new JSC VM. To save resources and simplify the communication between RN views in different parts of your native app, you can have multiple views powered by React Native that are associated with a single JS runtime. To do that, instead of using `[RCTRootView alloc] initWithURL`, use [`RCTBridge initWithBundleURL`](https://github.com/facebook/react-native/blob/master/React/Base/RCTBridge.h#L93) to create a bridge and then use `RCTRootView initWithBridge`.
+> Note that `RCTRootView initWithBundleURL` starts up a new JSC VM. To save resources and simplify the communication between RN views in different parts of your native app, you can have multiple views powered by React Native that are associated with a single JS runtime. To do that, instead of using `[RCTRootView alloc] initWithBundleURL`, use [`RCTBridge initWithBundleURL`](https://github.com/facebook/react-native/blob/master/React/Base/RCTBridge.h#L93) to create a bridge and then use `RCTRootView initWithBridge`.
diff --git a/archived_docs/version-0.62/integration-with-existing-apps.md b/archived_docs/version-0.62/integration-with-existing-apps.md
index dda3ac57934..371a0b734a3 100644
--- a/archived_docs/version-0.62/integration-with-existing-apps.md
+++ b/archived_docs/version-0.62/integration-with-existing-apps.md
@@ -394,7 +394,7 @@ We will, for debugging purposes, log that the event handler was invoked. Then, w
}
```
-> Note that `RCTRootView initWithURL` starts up a new JSC VM. To save resources and simplify the communication between RN views in different parts of your native app, you can have multiple views powered by React Native that are associated with a single JS runtime. To do that, instead of using `[RCTRootView alloc] initWithURL`, use [`RCTBridge initWithBundleURL`](https://github.com/facebook/react-native/blob/master/React/Base/RCTBridge.h#L93) to create a bridge and then use `RCTRootView initWithBridge`.
+> Note that `RCTRootView initWithBundleURL` starts up a new JSC VM. To save resources and simplify the communication between RN views in different parts of your native app, you can have multiple views powered by React Native that are associated with a single JS runtime. To do that, instead of using `[RCTRootView alloc] initWithBundleURL`, use [`RCTBridge initWithBundleURL`](https://github.com/facebook/react-native/blob/master/React/Base/RCTBridge.h#L93) to create a bridge and then use `RCTRootView initWithBridge`.
diff --git a/archived_docs/version-0.63/_integration-with-exisiting-apps-objc.md b/archived_docs/version-0.63/_integration-with-exisiting-apps-objc.md
index ef61f909d21..0f7603fda7b 100644
--- a/archived_docs/version-0.63/_integration-with-exisiting-apps-objc.md
+++ b/archived_docs/version-0.63/_integration-with-exisiting-apps-objc.md
@@ -272,7 +272,7 @@ You can add a new link on the main game menu to go to the "High Score" React Nat
}
```
-> Note that `RCTRootView initWithURL` starts up a new JSC VM. To save resources and simplify the communication between RN views in different parts of your native app, you can have multiple views powered by React Native that are associated with a single JS runtime. To do that, instead of using `[RCTRootView alloc] initWithURL`, use [`RCTBridge initWithBundleURL`](https://github.com/facebook/react-native/blob/master/React/Base/RCTBridge.h#L93) to create a bridge and then use `RCTRootView initWithBridge`.
+> Note that `RCTRootView initWithBundleURL` starts up a new JSC VM. To save resources and simplify the communication between RN views in different parts of your native app, you can have multiple views powered by React Native that are associated with a single JS runtime. To do that, instead of using `[RCTRootView alloc] initWithBundleURL`, use [`RCTBridge initWithBundleURL`](https://github.com/facebook/react-native/blob/master/React/Base/RCTBridge.h#L93) to create a bridge and then use `RCTRootView initWithBridge`.
> When moving your app to production, the `NSURL` can point to a pre-bundled file on disk via something like `[[NSBundle mainBundle] URLForResource:@"main" withExtension:@"jsbundle"];`. You can use the `react-native-xcode.sh` script in `node_modules/react-native/scripts/` to generate that pre-bundled file.
diff --git a/archived_docs/version-0.64/_integration-with-exisiting-apps-objc.md b/archived_docs/version-0.64/_integration-with-exisiting-apps-objc.md
index 1aa816ade81..3fac721c725 100644
--- a/archived_docs/version-0.64/_integration-with-exisiting-apps-objc.md
+++ b/archived_docs/version-0.64/_integration-with-exisiting-apps-objc.md
@@ -272,7 +272,7 @@ You can add a new link on the main game menu to go to the "High Score" React Nat
}
```
-> Note that `RCTRootView initWithURL` starts up a new JSC VM. To save resources and simplify the communication between RN views in different parts of your native app, you can have multiple views powered by React Native that are associated with a single JS runtime. To do that, instead of using `[RCTRootView alloc] initWithURL`, use [`RCTBridge initWithBundleURL`](https://github.com/facebook/react-native/blob/master/React/Base/RCTBridge.h#L93) to create a bridge and then use `RCTRootView initWithBridge`.
+> Note that `RCTRootView initWithBundleURL` starts up a new JSC VM. To save resources and simplify the communication between RN views in different parts of your native app, you can have multiple views powered by React Native that are associated with a single JS runtime. To do that, instead of using `[RCTRootView alloc] initWithBundleURL`, use [`RCTBridge initWithBundleURL`](https://github.com/facebook/react-native/blob/master/React/Base/RCTBridge.h#L93) to create a bridge and then use `RCTRootView initWithBridge`.
> When moving your app to production, the `NSURL` can point to a pre-bundled file on disk via something like `[[NSBundle mainBundle] URLForResource:@"main" withExtension:@"jsbundle"];`. You can use the `react-native-xcode.sh` script in `node_modules/react-native/scripts/` to generate that pre-bundled file.
diff --git a/archived_docs/version-0.65/_integration-with-exisiting-apps-objc.md b/archived_docs/version-0.65/_integration-with-exisiting-apps-objc.md
index 1aa816ade81..3fac721c725 100644
--- a/archived_docs/version-0.65/_integration-with-exisiting-apps-objc.md
+++ b/archived_docs/version-0.65/_integration-with-exisiting-apps-objc.md
@@ -272,7 +272,7 @@ You can add a new link on the main game menu to go to the "High Score" React Nat
}
```
-> Note that `RCTRootView initWithURL` starts up a new JSC VM. To save resources and simplify the communication between RN views in different parts of your native app, you can have multiple views powered by React Native that are associated with a single JS runtime. To do that, instead of using `[RCTRootView alloc] initWithURL`, use [`RCTBridge initWithBundleURL`](https://github.com/facebook/react-native/blob/master/React/Base/RCTBridge.h#L93) to create a bridge and then use `RCTRootView initWithBridge`.
+> Note that `RCTRootView initWithBundleURL` starts up a new JSC VM. To save resources and simplify the communication between RN views in different parts of your native app, you can have multiple views powered by React Native that are associated with a single JS runtime. To do that, instead of using `[RCTRootView alloc] initWithBundleURL`, use [`RCTBridge initWithBundleURL`](https://github.com/facebook/react-native/blob/master/React/Base/RCTBridge.h#L93) to create a bridge and then use `RCTRootView initWithBridge`.
> When moving your app to production, the `NSURL` can point to a pre-bundled file on disk via something like `[[NSBundle mainBundle] URLForResource:@"main" withExtension:@"jsbundle"];`. You can use the `react-native-xcode.sh` script in `node_modules/react-native/scripts/` to generate that pre-bundled file.
diff --git a/archived_docs/version-0.66/_integration-with-exisiting-apps-objc.md b/archived_docs/version-0.66/_integration-with-exisiting-apps-objc.md
index 1aa816ade81..3fac721c725 100644
--- a/archived_docs/version-0.66/_integration-with-exisiting-apps-objc.md
+++ b/archived_docs/version-0.66/_integration-with-exisiting-apps-objc.md
@@ -272,7 +272,7 @@ You can add a new link on the main game menu to go to the "High Score" React Nat
}
```
-> Note that `RCTRootView initWithURL` starts up a new JSC VM. To save resources and simplify the communication between RN views in different parts of your native app, you can have multiple views powered by React Native that are associated with a single JS runtime. To do that, instead of using `[RCTRootView alloc] initWithURL`, use [`RCTBridge initWithBundleURL`](https://github.com/facebook/react-native/blob/master/React/Base/RCTBridge.h#L93) to create a bridge and then use `RCTRootView initWithBridge`.
+> Note that `RCTRootView initWithBundleURL` starts up a new JSC VM. To save resources and simplify the communication between RN views in different parts of your native app, you can have multiple views powered by React Native that are associated with a single JS runtime. To do that, instead of using `[RCTRootView alloc] initWithBundleURL`, use [`RCTBridge initWithBundleURL`](https://github.com/facebook/react-native/blob/master/React/Base/RCTBridge.h#L93) to create a bridge and then use `RCTRootView initWithBridge`.
> When moving your app to production, the `NSURL` can point to a pre-bundled file on disk via something like `[[NSBundle mainBundle] URLForResource:@"main" withExtension:@"jsbundle"];`. You can use the `react-native-xcode.sh` script in `node_modules/react-native/scripts/` to generate that pre-bundled file.
diff --git a/archived_docs/version-0.67/_integration-with-exisiting-apps-objc.md b/archived_docs/version-0.67/_integration-with-exisiting-apps-objc.md
index abc26b8ee6a..a18e19ddb61 100644
--- a/archived_docs/version-0.67/_integration-with-exisiting-apps-objc.md
+++ b/archived_docs/version-0.67/_integration-with-exisiting-apps-objc.md
@@ -276,7 +276,7 @@ You can add a new link on the main game menu to go to the "High Score" React Nat
}
```
-> Note that `RCTRootView initWithURL` starts up a new JSC VM. To save resources and simplify the communication between RN views in different parts of your native app, you can have multiple views powered by React Native that are associated with a single JS runtime. To do that, instead of using `[RCTRootView alloc] initWithURL`, use [`RCTBridge initWithBundleURL`](https://github.com/facebook/react-native/blob/master/React/Base/RCTBridge.h#L93) to create a bridge and then use `RCTRootView initWithBridge`.
+> Note that `RCTRootView initWithBundleURL` starts up a new JSC VM. To save resources and simplify the communication between RN views in different parts of your native app, you can have multiple views powered by React Native that are associated with a single JS runtime. To do that, instead of using `[RCTRootView alloc] initWithBundleURL`, use [`RCTBridge initWithBundleURL`](https://github.com/facebook/react-native/blob/master/React/Base/RCTBridge.h#L93) to create a bridge and then use `RCTRootView initWithBridge`.
> When moving your app to production, the `NSURL` can point to a pre-bundled file on disk via something like `[[NSBundle mainBundle] URLForResource:@"main" withExtension:@"jsbundle"];`. You can use the `react-native-xcode.sh` script in `node_modules/react-native/scripts/` to generate that pre-bundled file.
diff --git a/archived_docs/version-0.68/_integration-with-exisiting-apps-objc.md b/archived_docs/version-0.68/_integration-with-exisiting-apps-objc.md
index abc26b8ee6a..a18e19ddb61 100644
--- a/archived_docs/version-0.68/_integration-with-exisiting-apps-objc.md
+++ b/archived_docs/version-0.68/_integration-with-exisiting-apps-objc.md
@@ -276,7 +276,7 @@ You can add a new link on the main game menu to go to the "High Score" React Nat
}
```
-> Note that `RCTRootView initWithURL` starts up a new JSC VM. To save resources and simplify the communication between RN views in different parts of your native app, you can have multiple views powered by React Native that are associated with a single JS runtime. To do that, instead of using `[RCTRootView alloc] initWithURL`, use [`RCTBridge initWithBundleURL`](https://github.com/facebook/react-native/blob/master/React/Base/RCTBridge.h#L93) to create a bridge and then use `RCTRootView initWithBridge`.
+> Note that `RCTRootView initWithBundleURL` starts up a new JSC VM. To save resources and simplify the communication between RN views in different parts of your native app, you can have multiple views powered by React Native that are associated with a single JS runtime. To do that, instead of using `[RCTRootView alloc] initWithBundleURL`, use [`RCTBridge initWithBundleURL`](https://github.com/facebook/react-native/blob/master/React/Base/RCTBridge.h#L93) to create a bridge and then use `RCTRootView initWithBridge`.
> When moving your app to production, the `NSURL` can point to a pre-bundled file on disk via something like `[[NSBundle mainBundle] URLForResource:@"main" withExtension:@"jsbundle"];`. You can use the `react-native-xcode.sh` script in `node_modules/react-native/scripts/` to generate that pre-bundled file.
diff --git a/archived_docs/version-0.69/_integration-with-exisiting-apps-objc.md b/archived_docs/version-0.69/_integration-with-exisiting-apps-objc.md
index abc26b8ee6a..a18e19ddb61 100644
--- a/archived_docs/version-0.69/_integration-with-exisiting-apps-objc.md
+++ b/archived_docs/version-0.69/_integration-with-exisiting-apps-objc.md
@@ -276,7 +276,7 @@ You can add a new link on the main game menu to go to the "High Score" React Nat
}
```
-> Note that `RCTRootView initWithURL` starts up a new JSC VM. To save resources and simplify the communication between RN views in different parts of your native app, you can have multiple views powered by React Native that are associated with a single JS runtime. To do that, instead of using `[RCTRootView alloc] initWithURL`, use [`RCTBridge initWithBundleURL`](https://github.com/facebook/react-native/blob/master/React/Base/RCTBridge.h#L93) to create a bridge and then use `RCTRootView initWithBridge`.
+> Note that `RCTRootView initWithBundleURL` starts up a new JSC VM. To save resources and simplify the communication between RN views in different parts of your native app, you can have multiple views powered by React Native that are associated with a single JS runtime. To do that, instead of using `[RCTRootView alloc] initWithBundleURL`, use [`RCTBridge initWithBundleURL`](https://github.com/facebook/react-native/blob/master/React/Base/RCTBridge.h#L93) to create a bridge and then use `RCTRootView initWithBridge`.
> When moving your app to production, the `NSURL` can point to a pre-bundled file on disk via something like `[[NSBundle mainBundle] URLForResource:@"main" withExtension:@"jsbundle"];`. You can use the `react-native-xcode.sh` script in `node_modules/react-native/scripts/` to generate that pre-bundled file.
diff --git a/cndocs/_getting-started-linux-android.md b/cndocs/_getting-started-linux-android.md
index 8a0013c1246..5977e1744ec 100644
--- a/cndocs/_getting-started-linux-android.md
+++ b/cndocs/_getting-started-linux-android.md
@@ -55,7 +55,7 @@ React Native 当前需要 Java Development Kit [JDK] 17。你可以在命令行
> 也可以尝试参考这里的做法[设置阿里云的 maven 镜像源](https://github.com/scwang90/SmartRefreshLayout/issues/1376#issuecomment-938422964),但这个做法可能随 gradle 或者 rn 版本的不同而失效。
-#### 1. 安装 Android Studio
+
| The dialog's title. Passing `null` or empty string will hide the title. |
+| message | string | An optional message that appears below the dialog's title. |
+| buttons | [Buttons](alert#buttons) | An optional array containg buttons configuration. |
+| options | [Options](alert#options)
Android
| An optional Alert configuration for the Android. |
+
+---
+
+### `prompt()`
iOS
+
+```jsx
+static prompt(title, message?, callbackOrButtons?, type?, defaultValue?, keyboardType?)
+```
+
+Create and display a prompt to enter some text in form of Alert.
+
+**参数:**
+
+| 名称 | 类型 | 说明 |
+| ----------------- | ------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
+| title | string
Required
| The dialog's title. |
+| message | string | An optional message that appears above the text input. |
+| callbackOrButtons | function[Buttons](alert#buttons) | If passed a function, it will be called with the prompt's value `(text: string) => void`, when the user taps 'OK'.If passed an array, buttons will be configured based on the array content. |
+| 类型 | [AlertType](alert#alerttype) | This configures the text input. |
+| defaultValue | string | The default text in text input. |
+| keyboardType | string | The keyboard type of first text field (if exists). One of TextInput [keyboardTypes](textinput#keyboardtype). |
+
+---
+
+## 类型定义
+
+### AlertButtonStyle
| string |
+
+---
+
+### `getSectionKeys()`
+
+```tsx
+static getSectionKeys(): string[];
+```
+
+Returns an array of strings.
+
+---
+
+### `getSections()`
+
+```tsx
+static getSections(): Record;
+```
+
+Returns a [Runnables](appregistry#runnables) object.
+
+---
+
+### `registerCancellableHeadlessTask()`
+
+```tsx
+static registerCancellableHeadlessTask(
+ taskKey: string,
+ taskProvider: TaskProvider,
+ taskCancelProvider: TaskCancelProvider,
+);
+```
+
+Register a headless task which can be cancelled. A headless task is a bit of code that runs without a UI.
+
+**Parameters:**
+
+| Name | Type | Description |
+| ------------------------------------------------------------------------------------- | ---------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
+| taskKey
Required
| string | The native id for this task instance that was used when startHeadlessTask was called. |
+| taskProvider
Required
| [TaskProvider](appregistry#taskprovider) | A promise returning function that takes some data passed from the native side as the only argument. When the promise is resolved or rejected the native side is notified of this event and it may decide to destroy the JS context. |
+| taskCancelProvider
Required
| [TaskCancelProvider](appregistry#taskcancelprovider) | a void returning function that takes no arguments; when a cancellation is requested, the function being executed by taskProvider should wrap up and return ASAP. |
+
+---
+
+### `registerComponent()`
+
+```tsx
+static registerComponent(
+ appKey: string,
+ getComponentFunc: ComponentProvider,
+ section?: boolean,
+): string;
+```
+
+**参数:**
+
+| 名称 | 类型 |
+| ---------------------------------------------------------------------- | ----------------- |
+| appKey
| [AppConfig](appregistry#appconfig)[] |
+
+---
+
+### `registerHeadlessTask()`
+
+```tsx
+static registerHeadlessTask(
+ taskKey: string,
+ taskProvider: TaskProvider,
+);
+```
+
+Register a headless task. A headless task is a bit of code that runs without a UI.
+
+This is a way to run tasks in JavaScript while your app is in the background. It can be used, for example, to sync fresh data, handle push notifications, or play music.
+
+**Parameters:**
+
+| Name | Type | Description |
+| --------------------------------------------------------------------------- | ---------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
+| taskKey
Required
| string | The native id for this task instance that was used when startHeadlessTask was called. |
+| taskProvider
Required
| [TaskProvider](appregistry#taskprovider) | A promise returning function that takes some data passed from the native side as the only argument. When the promise is resolved or rejected the native side is notified of this event and it may decide to destroy the JS context. |
+
+---
+
+### `registerRunnable()`
+
+```tsx
+static registerRunnable(appKey: string, func: Runnable): string;
+```
+
+**Parameters:**
+
+| Name | Type |
+| ----------------------------------------------------------- | -------- |
+| appKey
| function |
+
+A valid `hook` function accepts the following as arguments:
+
+| Name | Type |
+| ---------------------------------------------------------------------------- | ------------------ |
+| component
Required
| ComponentProvider |
+| scopedPerformanceLogger
Required
| IPerformanceLogger |
+
+The function must also return a React Component.
+
+---
+
+### `setWrapperComponentProvider()`
+
+```tsx
+static setWrapperComponentProvider(
+ provider: WrapperComponentProvider,
+);
+```
+
+**Parameters:**
+
+| Name | Type |
+| ------------------------------------------------------------- | ----------------- |
+| provider
| number | The native id for this task instance to keep track of its execution. |
+| taskKey
Required
| string | The key for the task to start. |
+| data
Required
| any | The data to pass to the task. |
+
+---
+
+### `unmountApplicationComponentAtRootTag()`
+
+```tsx
+static unmountApplicationComponentAtRootTag(rootTag: number);
+```
+
+Stops an application when a view should be destroyed.
+
+**Parameters:**
+
+| Name | Type |
+| ------------------------------------------------------------ | ------ |
+| rootTag
Required
| number |
+
+## Type Definitions
+
+### AppConfig
+
+Application configuration for the `registerConfig` method.
+
+| Type |
+| ------ |
+| object |
+
+**Properties:**
+
+| Name | Type |
+| ----------------------------------------------------------- | ----------------- |
+| appKey
Required
| string |
+| component | ComponentProvider |
+| run | function |
+| section | boolean |
+
+> **Note:** Every config is expected to set either `component` or `run` function.
+
+### Registry
+
+| Type |
+| ------ |
+| object |
+
+**Properties:**
+
+| Name | Type |
+| --------- | ------------------------------------------ |
+| runnables | array of [Runnables](appregistry#runnable) |
+| sections | array of strings |
+
+### Runnable
+
+| Type |
+| ------ |
+| object |
+
+**Properties:**
+
+| Name | Type |
+| --------- | ----------------- |
+| component | ComponentProvider |
+| run | function |
+
+### Runnables
+
+An object with key of `appKey` and value of type of [`Runnable`](appregistry#runnable).
+
+| Type |
+| ------ |
+| object |
+
+### Task
+
+A `Task` is a function that accepts any data as argument and returns a Promise that resolves to `undefined`.
+
+| Type |
+| -------- |
+| function |
+
+### TaskCanceller
+
+A `TaskCanceller` is a function that accepts no argument and returns void.
+
+| Type |
+| -------- |
+| function |
+
+### TaskCancelProvider
+
+A valid `TaskCancelProvider` is a function that returns a [`TaskCanceller`](appregistry#taskcanceller).
+
+| Type |
+| -------- |
+| function |
+
+### TaskProvider
+
+A valid `TaskProvider` is a function that returns a [`Task`](appregistry#task).
+
+| Type |
+| -------- |
+| function |
diff --git a/cnwebsite/versioned_docs/version-0.75/appstate.md b/cnwebsite/versioned_docs/version-0.75/appstate.md
new file mode 100644
index 00000000000..e8ca1cb56f4
--- /dev/null
+++ b/cnwebsite/versioned_docs/version-0.75/appstate.md
@@ -0,0 +1,114 @@
+---
+id: appstate
+title: AppState
+---
+
+`AppState`能告诉你应用当前是在前台还是在后台,并且能在状态变化的时候通知你。
+
+AppState 通常在处理推送通知的时候用来决定内容和对应的行为。
+
+### App States
+
+- `active` - 应用正在前台运行
+- `background` - 应用正在后台运行。用户可能面对以下几种情况:
+ - 在别的应用中
+ - 停留在桌面
+ - 对 Android 来说还可能处在另一个`Activity`中(即便是由你的应用拉起的)
+- [iOS] `inactive` - 此状态表示应用正在前后台的切换过程中,或是处在系统的多任务视图,又或是处在来电状态中。
+
+要了解更多信息,可以阅读[Apple 的文档](https://developer.apple.com/documentation/uikit/app_and_scenes/managing_your_app_s_life_cycle)。
+
+## 基本用法
+
+要获取当前的状态,你可以使用`AppState.currentState`,这个变量会一直保持更新。不过在启动的过程中,`currentState`可能为 null,直到`AppState`从原生代码得到通知为止。
+
+```SnackPlayer name=AppState%20Example
+import React, {useRef, useState, useEffect} from 'react';
+import {AppState, StyleSheet, Text, View} from 'react-native';
+
+const AppStateExample = () => {
+ const appState = useRef(AppState.currentState);
+ const [appStateVisible, setAppStateVisible] = useState(appState.current);
+
+ useEffect(() => {
+ const subscription = AppState.addEventListener('change', nextAppState => {
+ if (
+ appState.current.match(/inactive|background/) &&
+ nextAppState === 'active'
+ ) {
+ console.log('App has come to the foreground!');
+ }
+
+ appState.current = nextAppState;
+ setAppStateVisible(appState.current);
+ console.log('AppState', appState.current);
+ });
+
+ return () => {
+ subscription.remove();
+ };
+ }, []);
+
+ return (
+
+ Current state is: {appStateVisible}
+
+ );
+};
+
+const styles = StyleSheet.create({
+ container: {
+ flex: 1,
+ justifyContent: 'center',
+ alignItems: 'center',
+ },
+});
+
+export default AppStateExample;
+```
+
+上面的这个例子只会显示"Current state is: active",这是因为应用只有在`active`状态下才能被用户看到。并且 null 状态只会在一开始的一瞬间出现。如果你想尝试这段代码,我们建议使用自己的设备而不是在上面网页中的嵌入式预览。
+
+---
+
+# 文档
+
+## 事件
+
+### `blur`
diff --git a/cnwebsite/versioned_docs/version-0.75/custom-webview-android.md b/cnwebsite/versioned_docs/version-0.75/custom-webview-android.md
new file mode 100644
index 00000000000..f1cfda63891
--- /dev/null
+++ b/cnwebsite/versioned_docs/version-0.75/custom-webview-android.md
@@ -0,0 +1,258 @@
+---
+id: custom-webview-android
+title: Custom WebView
+---
+
+While the built-in web view has a lot of features, it is not possible to handle every use-case in React Native. You can, however, extend the web view with native code without forking React Native or duplicating all the existing web view code.
+
+Before you do this, you should be familiar with the concepts in [native UI components](native-components-android). You should also familiarise yourself with the [native code for web views](https://github.com/facebook/react-native/blob/master/ReactAndroid/src/main/java/com/facebook/react/views/webview/ReactWebViewManager.java), as you will have to use this as a reference when implementing new features—although a deep understanding is not required.
+
+## Native Code
+
+To get started, you'll need to create a subclass of `ReactWebViewManager`, `ReactWebView`, and `ReactWebViewClient`. In your view manager, you'll then need to override:
+
+* `createReactWebViewInstance`
+* `getName`
+* `addEventEmitters`
+
+```java
+@ReactModule(name = CustomWebViewManager.REACT_CLASS)
+public class CustomWebViewManager extends ReactWebViewManager {
+ /* This name must match what we're referring to in JS */
+ protected static final String REACT_CLASS = "RCTCustomWebView";
+
+ protected static class CustomWebViewClient extends ReactWebViewClient { }
+
+ protected static class CustomWebView extends ReactWebView {
+ public CustomWebView(ThemedReactContext reactContext) {
+ super(reactContext);
+ }
+ }
+
+ @Override
+ protected ReactWebView createReactWebViewInstance(ThemedReactContext reactContext) {
+ return new CustomWebView(reactContext);
+ }
+
+ @Override
+ public String getName() {
+ return REACT_CLASS;
+ }
+
+ @Override
+ protected void addEventEmitters(ThemedReactContext reactContext, WebView view) {
+ view.setWebViewClient(new CustomWebViewClient());
+ }
+}
+```
+
+You'll need to follow the usual steps to [register the module](native-modules-android.md#register-the-module).
+
+### Adding New Properties
+
+To add a new property, you'll need to add it to `CustomWebView`, and then expose it in `CustomWebViewManager`.
+
+```java
+public class CustomWebViewManager extends ReactWebViewManager {
+ ...
+
+ protected static class CustomWebView extends ReactWebView {
+ public CustomWebView(ThemedReactContext reactContext) {
+ super(reactContext);
+ }
+
+ protected @Nullable String mFinalUrl;
+
+ public void setFinalUrl(String url) {
+ mFinalUrl = url;
+ }
+
+ public String getFinalUrl() {
+ return mFinalUrl;
+ }
+ }
+
+ ...
+
+ @ReactProp(name = "finalUrl")
+ public void setFinalUrl(WebView view, String url) {
+ ((CustomWebView) view).setFinalUrl(url);
+ }
+}
+```
+
+### Adding New Events
+
+For events, you'll first need to make create event subclass.
+
+```java
+// NavigationCompletedEvent.java
+public class NavigationCompletedEvent extends Event {
+ private WritableMap mParams;
+
+ public NavigationCompletedEvent(int viewTag, WritableMap params) {
+ super(viewTag);
+ this.mParams = params;
+ }
+
+ @Override
+ public String getEventName() {
+ return "navigationCompleted";
+ }
+
+ @Override
+ public void dispatch(RCTEventEmitter rctEventEmitter) {
+ init(getViewTag());
+ rctEventEmitter.receiveEvent(getViewTag(), getEventName(), mParams);
+ }
+}
+```
+
+You can trigger the event in your web view client. You can hook existing handlers if your events are based on them.
+
+You should refer to [ReactWebViewManager.java](https://github.com/facebook/react-native/blob/master/ReactAndroid/src/main/java/com/facebook/react/views/webview/ReactWebViewManager.java) in the React Native codebase to see what handlers are available and how they are implemented. You can extend any methods here to provide extra functionality.
+
+```java
+public class NavigationCompletedEvent extends Event {
+ private WritableMap mParams;
+
+ public NavigationCompletedEvent(int viewTag, WritableMap params) {
+ super(viewTag);
+ this.mParams = params;
+ }
+
+ @Override
+ public String getEventName() {
+ return "navigationCompleted";
+ }
+
+ @Override
+ public void dispatch(RCTEventEmitter rctEventEmitter) {
+ init(getViewTag());
+ rctEventEmitter.receiveEvent(getViewTag(), getEventName(), mParams);
+ }
+}
+
+// CustomWebViewManager.java
+protected static class CustomWebViewClient extends ReactWebViewClient {
+ @Override
+ public boolean shouldOverrideUrlLoading(WebView view, String url) {
+ boolean shouldOverride = super.shouldOverrideUrlLoading(view, url);
+ String finalUrl = ((CustomWebView) view).getFinalUrl();
+
+ if (!shouldOverride && url != null && finalUrl != null && new String(url).equals(finalUrl)) {
+ final WritableMap params = Arguments.createMap();
+ dispatchEvent(view, new NavigationCompletedEvent(view.getId(), params));
+ }
+
+ return shouldOverride;
+ }
+}
+```
+
+Finally, you'll need to expose the events in `CustomWebViewManager` through `getExportedCustomDirectEventTypeConstants`. Note that currently, the default implementation returns `null`, but this may change in the future.
+
+```java
+public class CustomWebViewManager extends ReactWebViewManager {
+ ...
+
+ @Override
+ public @Nullable
+ Map getExportedCustomDirectEventTypeConstants() {
+ Map export = super.getExportedCustomDirectEventTypeConstants();
+ if (export == null) {
+ export = MapBuilder.newHashMap();
+ }
+ export.put("navigationCompleted", MapBuilder.of("registrationName", "onNavigationCompleted"));
+ return export;
+ }
+}
+```
+
+## JavaScript Interface
+
+To use your custom web view, you'll need to create a class for it. Your class must:
+
+* Export all the prop types from `WebView.propTypes`
+* Return a `WebView` component with the prop `nativeConfig.component` set to your native component (see below)
+
+To get your native component, you must use `requireNativeComponent`: the same as for regular custom components. However, you must pass in an extra third argument, `WebView.extraNativeComponentConfig`. This third argument contains prop types that are only required for native code.
+
+```jsx
+import React, {Component, PropTypes} from 'react';
+import {WebView, requireNativeComponent} from 'react-native';
+
+export default class CustomWebView extends Component {
+ static propTypes = WebView.propTypes;
+
+ render() {
+ return (
+
+ );
+ }
+}
+
+const RCTCustomWebView = requireNativeComponent(
+ 'RCTCustomWebView',
+ CustomWebView,
+ WebView.extraNativeComponentConfig
+);
+```
+
+If you want to add custom props to your native component, you can use `nativeConfig.props` on the web view.
+
+For events, the event handler must always be set to a function. This means it isn't safe to use the event handler directly from `this.props`, as the user might not have provided one. The standard approach is to create a event handler in your class, and then invoking the event handler given in `this.props` if it exists.
+
+If you are unsure how something should be implemented from the JS side, look at [WebView.android.js](https://github.com/facebook/react-native/blob/master/Libraries/Components/WebView/WebView.android.js) in the React Native source.
+
+```jsx
+export default class CustomWebView extends Component {
+ static propTypes = {
+ ...WebView.propTypes,
+ finalUrl: PropTypes.string,
+ onNavigationCompleted: PropTypes.func,
+ };
+
+ static defaultProps = {
+ finalUrl: 'about:blank',
+ };
+
+ _onNavigationCompleted = (event) => {
+ const {onNavigationCompleted} = this.props;
+ onNavigationCompleted && onNavigationCompleted(event);
+ };
+
+ render() {
+ return (
+
+ );
+ }
+}
+```
+
+Just like for regular native components, you must provide all your prop types in the component to have them forwarded on to the native component. However, if you have some prop types that are only used internally in component, you can add them to the `nativeOnly` property of the third argument previously mentioned. For event handlers, you have to use the value `true` instead of a regular prop type.
+
+For example, if you wanted to add an internal event handler called `onScrollToBottom`, you would use,
+
+```jsx
+const RCTCustomWebView = requireNativeComponent(
+ 'RCTCustomWebView',
+ CustomWebView,
+ {
+ ...WebView.extraNativeComponentConfig,
+ nativeOnly: {
+ ...WebView.extraNativeComponentConfig.nativeOnly,
+ onScrollToBottom: true,
+ },
+ }
+);
+```
diff --git a/cnwebsite/versioned_docs/version-0.75/custom-webview-ios.md b/cnwebsite/versioned_docs/version-0.75/custom-webview-ios.md
new file mode 100644
index 00000000000..d73aa27cf75
--- /dev/null
+++ b/cnwebsite/versioned_docs/version-0.75/custom-webview-ios.md
@@ -0,0 +1,232 @@
+---
+id: custom-webview-ios
+title: Custom WebView
+---
+
+While the built-in web view has a lot of features, it is not possible to handle every use-case in React Native. You can, however, extend the web view with native code without forking React Native or duplicating all the existing web view code.
+
+Before you do this, you should be familiar with the concepts in [native UI components](native-components-ios). You should also familiarise yourself with the [native code for web views](https://github.com/facebook/react-native/blob/master/React/Views/RCTWebViewManager.m), as you will have to use this as a reference when implementing new features—although a deep understanding is not required.
+
+## Native Code
+
+Like for regular native components, you need a view manager and an web view.
+
+For the view, you'll need to make a subclass of `RCTWebView`.
+
+```objc
+// RCTCustomWebView.h
+#import
+
+@interface RCTCustomWebView : RCTWebView
+
+@end
+
+// RCTCustomWebView.m
+#import "RCTCustomWebView.h"
+
+@interface RCTCustomWebView ()
+
+@end
+
+@implementation RCTCustomWebView { }
+
+@end
+```
+
+For the view manager, you need to make a subclass `RCTWebViewManager`. You must still include:
+
+* `(UIView *)view` that returns your custom view
+* The `RCT_EXPORT_MODULE()` tag
+
+```objc
+// RCTCustomWebViewManager.h
+#import
+
+@interface RCTCustomWebViewManager : RCTWebViewManager
+
+@end
+
+// RCTCustomWebViewManager.m
+#import "RCTCustomWebViewManager.h"
+#import "RCTCustomWebView.h"
+
+@interface RCTCustomWebViewManager ()
+
+@end
+
+@implementation RCTCustomWebViewManager { }
+
+RCT_EXPORT_MODULE()
+
+- (UIView *)view
+{
+ RCTCustomWebView *webView = [RCTCustomWebView new];
+ webView.delegate = self;
+ return webView;
+}
+
+@end
+```
+
+### Adding New Events and Properties
+
+Adding new properties and events is the same as regular UI components. For properties, you define an `@property` in the header. For events, you define a `RCTDirectEventBlock` in the view's `@interface`.
+
+```objc
+// RCTCustomWebView.h
+@property (nonatomic, copy) NSString *finalUrl;
+
+// RCTCustomWebView.m
+@interface RCTCustomWebView ()
+
+@property (nonatomic, copy) RCTDirectEventBlock onNavigationCompleted;
+
+@end
+```
+
+Then expose it in the view manager's `@implementation`.
+
+```objc
+// RCTCustomWebViewManager.m
+RCT_EXPORT_VIEW_PROPERTY(onNavigationCompleted, RCTDirectEventBlock)
+RCT_EXPORT_VIEW_PROPERTY(finalUrl, NSString)
+```
+
+### Extending Existing Events
+
+You should refer to [RCTWebView.m](https://github.com/facebook/react-native/blob/master/React/Views/RCTWebView.m) in the React Native codebase to see what handlers are available and how they are implemented. You can extend any methods here to provide extra functionality.
+
+By default, most methods aren't exposed from RCTWebView. If you need to expose them, you need to create an [Objective C category](https://developer.apple.com/library/content/documentation/Cocoa/Conceptual/ProgrammingWithObjectiveC/CustomizingExistingClasses/CustomizingExistingClasses.html), and then expose all the methods you need to use.
+
+```objc
+// RCTWebView+Custom.h
+#import
+
+@interface RCTWebView (Custom)
+- (BOOL)webView:(__unused UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType;
+- (NSMutableDictionary *)baseEvent;
+@end
+```
+
+Once these are exposed, you can reference them in your custom web view class.
+
+```objc
+// RCTCustomWebView.m
+
+// Remember to import the category file.
+#import "RCTWebView+Custom.h"
+
+- (BOOL)webView:(__unused UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request
+ navigationType:(UIWebViewNavigationType)navigationType
+{
+ BOOL allowed = [super webView:webView shouldStartLoadWithRequest:request navigationType:navigationType];
+
+ if (allowed) {
+ NSString* url = request.URL.absoluteString;
+ if (url && [url isEqualToString:_finalUrl]) {
+ if (_onNavigationCompleted) {
+ NSMutableDictionary *event = [self baseEvent];
+ _onNavigationCompleted(event);
+ }
+ }
+ }
+
+ return allowed;
+}
+```
+
+## JavaScript Interface
+
+To use your custom web view, you'll need to create a class for it. Your class must:
+
+* Export all the prop types from `WebView.propTypes`
+* Return a `WebView` component with the prop `nativeConfig.component` set to your native component (see below)
+
+To get your native component, you must use `requireNativeComponent`: the same as for regular custom components. However, you must pass in an extra third argument, `WebView.extraNativeComponentConfig`. This third argument contains prop types that are only required for native code.
+
+```jsx
+import React, {Component, PropTypes} from 'react';
+import {WebView, requireNativeComponent, NativeModules} from 'react-native';
+const {CustomWebViewManager} = NativeModules;
+
+export default class CustomWebView extends Component {
+ static propTypes = WebView.propTypes;
+
+ render() {
+ return (
+
+ );
+ }
+}
+
+const RCTCustomWebView = requireNativeComponent(
+ 'RCTCustomWebView',
+ CustomWebView,
+ WebView.extraNativeComponentConfig
+);
+```
+
+If you want to add custom props to your native component, you can use `nativeConfig.props` on the web view. For iOS, you should also set the `nativeConfig.viewManager` prop with your custom WebView ViewManager as in the example above.
+
+For events, the event handler must always be set to a function. This means it isn't safe to use the event handler directly from `this.props`, as the user might not have provided one. The standard approach is to create a event handler in your class, and then invoking the event handler given in `this.props` if it exists.
+
+If you are unsure how something should be implemented from the JS side, look at [WebView.ios.js](https://github.com/facebook/react-native/blob/master/Libraries/Components/WebView/WebView.ios.js) in the React Native source.
+
+```jsx
+export default class CustomWebView extends Component {
+ static propTypes = {
+ ...WebView.propTypes,
+ finalUrl: PropTypes.string,
+ onNavigationCompleted: PropTypes.func,
+ };
+
+ static defaultProps = {
+ finalUrl: 'about:blank',
+ };
+
+ _onNavigationCompleted = (event) => {
+ const {onNavigationCompleted} = this.props;
+ onNavigationCompleted && onNavigationCompleted(event);
+ };
+
+ render() {
+ return (
+
+ );
+ }
+}
+```
+
+Just like for regular native components, you must provide all your prop types in the component to have them forwarded on to the native component. However, if you have some prop types that are only used internally in component, you can add them to the `nativeOnly` property of the third argument previously mentioned. For event handlers, you have to use the value `true` instead of a regular prop type.
+
+For example, if you wanted to add an internal event handler called `onScrollToBottom`, you would use,
+
+```jsx
+const RCTCustomWebView = requireNativeComponent(
+ 'RCTCustomWebView',
+ CustomWebView,
+ {
+ ...WebView.extraNativeComponentConfig,
+ nativeOnly: {
+ ...WebView.extraNativeComponentConfig.nativeOnly,
+ onScrollToBottom: true,
+ },
+ }
+);
+```
diff --git a/cnwebsite/versioned_docs/version-0.75/datepickerandroid.md b/cnwebsite/versioned_docs/version-0.75/datepickerandroid.md
new file mode 100644
index 00000000000..b8348b8b46c
--- /dev/null
+++ b/cnwebsite/versioned_docs/version-0.75/datepickerandroid.md
@@ -0,0 +1,84 @@
+---
+id: datepickerandroid
+title: 🚧 DatePickerAndroid
+---
+
+> **Deprecated.** Use one of the [community packages](https://reactnative.directory/?search=datepicker) instead.
+
+本组件会打开一个标准的 Android 日期选择器的对话框。
+
+### 示例
+
+```jsx
+try {
+ const {
+ action,
+ year,
+ month,
+ day
+ } = await DatePickerAndroid.open({
+ // 要设置默认值为今天的话,使用`new Date()`即可。
+ // 下面显示的会是2020年5月25日。月份是从0开始算的。
+ date: new Date(2020, 4, 25)
+ });
+ if (action !== DatePickerAndroid.dismissedAction) {
+ // 这里开始可以处理用户选好的年月日三个参数:year, month (0-11), day
+ }
+} catch ({ code, message }) {
+ console.warn('Cannot open date picker', message);
+}
+```
+
+### 查看方法
+
+- [`open`](datepickerandroid.md#open)
+- [`dateSetAction`](datepickerandroid.md#datesetaction)
+- [`dismissedAction`](datepickerandroid.md#dismissedaction)
+
+---
+
+# 文档
+
+## 方法
+
+### `open()`
+
+```jsx
+static open(options)
+```
+
+打开一个标准的 Android 日期选择器的对话框。
+
+可选的`options`对象的 key 值如下:
+
+- `date` (`Date`对象或毫秒时间戳) - 默认显示的日期
+- `minDate` (`Date`对象或毫秒时间戳) - 可选的最小日期
+- `maxDate` (`Date`对象或毫秒时间戳) - 可选的最大日期
+- `mode` (`enum('calendar', 'spinner', 'default')`) - 设置选择器的模式:
+ - 'calendar': Show a date picker in calendar mode.
+ - 'spinner': Show a date picker in spinner mode.
+ - 'default': Show a default native date picker(spinner/calendar) based on android versions.
+
+在用户选好日期后返回一个 Promise,回调参数为一个对象,其中包含有`action`, `year`, `month` (0-11), `day`。如果用户取消了对话框,Promise 仍然会执行,返回的 action 为`DatePickerAndroid.dismissedAction`,其他几项参数则为 undefined。所以请在使用其他值之前**务必**先检查`action`的值是否为`DatePickerAndroid.dateSetAction`。
+
+Note the native date picker dialog has some UI glitches on Android 4 and lower when using the `minDate` and `maxDate` options.
+
+---
+
+### `dateSetAction()`
+
+```jsx
+static dateSetAction()
+```
+
+已选中一个日期。
+
+---
+
+### `dismissedAction()`
+
+```jsx
+static dismissedAction()
+```
+
+对话框已被取消。
diff --git a/cnwebsite/versioned_docs/version-0.75/datepickerios.md b/cnwebsite/versioned_docs/version-0.75/datepickerios.md
new file mode 100644
index 00000000000..371eb04971e
--- /dev/null
+++ b/cnwebsite/versioned_docs/version-0.75/datepickerios.md
@@ -0,0 +1,178 @@
+---
+id: datepickerios
+title: 🚧 DatePickerIOS
+---
+
+> **Deprecated.** Use one of the [community packages](https://reactnative.directory/?search=datepicker) instead.
+
+使用`DatePickerIOS`来在 iOS 平台上渲染一个日期/时间选择器。这是一个受约束的(Controlled)组件,所以你必须监听`onDateChange`回调函数并且及时更新`date`属性来使得组件更新,否则用户的修改会立刻被撤销来确保当前显示值和`props.date`一致。
+
+### 示例
+
+```
+import React, { Component } from 'react'
+import {
+ DatePickerIOS,
+ View,
+ StyleSheet,
+} from 'react-native'
+
+export default class App extends Component {
+ constructor(props) {
+ super(props);
+ this.state = { chosenDate: new Date() };
+
+ this.setDate = this.setDate.bind(this);
+ }
+
+ setDate(newDate) {
+ this.setState({chosenDate: newDate})
+ }
+
+ render() {
+ return (
+
+
+
+ )
+ }
+}
+
+const styles = StyleSheet.create({
+ container: {
+ flex: 1,
+ justifyContent: 'center'
+ },
+})
+```
+
+
+
+---
+
+# 文档
+
+## Props
+
+### `date`
+
+当前被选中的日期。
+
+| 类型 | 必需 |
+| ---- | ---- |
+| Date | 是 |
+
+---
+
+### `onChange`
+
+Date change handler.
+
+This is called when the user changes the date or time in the UI. The first and only argument is an Event. For getting the date the picker was changed to, use onDateChange instead.
+
+| 类型 | Required |
+| -------- | -------- |
+| function | No |
+
+---
+
+### `onDateChange`
+
+日期/时间变化的监听函数。
+
+当用户修改日期或时间时调用此回调函数。唯一的参数是一个日期对象,表示新的日期和时间。
+
+| 类型 | 必需 |
+| -------- | ---- |
+| function | 是 |
+
+---
+
+### `maximumDate`
+
+可选的最大日期。
+
+限制可选的日期/时间范围。
+
+| 类型 | 必需 |
+| ---- | ---- |
+| Date | 否 |
+
+Example with `maximumDate` set to December 31, 2017:
+
+
+
+Install the [Expo](https://expo.io) client app on your iOS or Android phone and connect to the same wireless network as your computer. On Android, use the Expo app to scan the QR code from your terminal to open your project. On iOS, use the built-in QR code scanner of the Camera app.
+
+
Modifying your app
+
+Now that you have successfully run the app, let's modify it. Open `App.js` in your text editor of choice and edit some lines. The application should reload automatically once you save your changes.
+
+
That's it!
+
+Congratulations! You've successfully run and modified your first React Native app.
+
+
+
+
Now what?
+
+Expo also has [docs](https://docs.expo.io) you can reference if you have questions specific to the tool. You can also ask for help at [Expo forums](https://forums.expo.io).
+
+These tools help you get started quickly, but before committing to building your app with Expo CLI, [read about the limitations](https://docs.expo.io/versions/latest/introduction/why-not-expo/).
+
+If you have a problem with Expo, before creating a new issue, please see if there's an existing issue about it:
+
+- in the [Expo CLI issues](https://github.com/expo/expo-cli/issues) (for issues related to Expo CLI), or
+- in the [Expo issues](https://github.com/expo/expo/issues) (for issues about the Expo client or SDK).
+
+If you're curious to learn more about React Native, check out the [Introduction to React Native](getting-started).
+
+
Running your app on a simulator or virtual device
+
+Expo CLI allows you to run your React Native app on a physical device without setting up a development environment. If you want to run your app on the iOS Simulator or an Android Virtual Device, please refer to the instructions for "React Native CLI Quickstart" to learn how to install Xcode or set up your Android development environment.
+
+Once you've set these up, you can launch your app on an Android Virtual Device by running `npm run android`, or on the iOS Simulator by running `npm run ios` (macOS only).
+
+
Caveats
+
+Because you don't build any native code when using Expo to create a project, it's not possible to include custom native modules beyond the React Native APIs and components that are available in the Expo client app.
+
+If you know that you'll eventually need to include your own native code, Expo is still a good way to get started. In that case you'll need to "[eject](https://docs.expo.io/versions/latest/workflow/customizing/)" eventually to create your own native builds. If you do eject, the "React Native CLI Quickstart" instructions will be required to continue working on your project.
+
+Expo CLI configures your project to use the most recent React Native version that is supported by the Expo client app. The Expo client app usually gains support for a given React Native version about a week after the React Native version is released as stable. You can check [this document](https://docs.expo.io/versions/latest/sdk/overview/#sdk-version) to find out what versions are supported.
+
+If you're integrating React Native into an existing project, you'll want to skip Expo CLI and go directly to setting up the native build environment. Select "React Native CLI Quickstart" above for instructions on configuring a native build environment for React Native.
+
+
+
+
+根据你所使用的操作系统、针对的目标平台不同,具体步骤有所不同。如果想同时开发 iOS 和 Android 也没问题,你只需要先选一个平台开始,另一个平台的环境搭建只是稍有不同。
+
+如果`阅读完本文档`后还碰到很多环境搭建的问题,我们建议你还可以再看看[求助讨论区](https://github.com/reactnativecn/react-native-website/issues)。注意!视频教程或者其他网络上的博客和文章可能和本文档有所出入,请以最新版本的本文档所述为准!
+
+#### 开发平台
+
+
+
+
+#### 目标平台
+
+
+
+
+[//]: # 'macOS, Android'
+
+
+
+
+
+
+[//]: # 'macOS, iOS'
+
+
+
+
+
+
+
+
+
+#### 目标平台
+
+
+
+
+[//]: # 'Windows, Android'
+
+
+
+
+
+
+[//]: # 'Windows, iOS'
+
+## 暂不支持
+
+> 苹果公司目前只允许在 Mac 电脑上开发 iOS 应用。如果你没有 Mac 电脑,那么只能考虑使用`沙盒环境`,或者先开发 Android 应用了。
+
+
+
+
+
+
+
+#### 目标平台
+
+
+
+
+[//]: # 'Linux, Android'
+
+
+
+
+
+
+[//]: # 'Linux, iOS'
+
+## 暂不支持
+
+> 苹果公司目前只允许在 Mac 电脑上开发 iOS 应用。如果你没有 Mac 电脑,那么只能考虑使用`沙盒环境`,或者先开发 Android 应用了。
+
+
+
+
+
+
+
+
+
diff --git a/cnwebsite/versioned_docs/version-0.75/glossary.md b/cnwebsite/versioned_docs/version-0.75/glossary.md
new file mode 100644
index 00000000000..f81e75bfaab
--- /dev/null
+++ b/cnwebsite/versioned_docs/version-0.75/glossary.md
@@ -0,0 +1,48 @@
+---
+id: architecture-glossary
+title: 术语表
+---
+
+## Fabric 渲染器(Fabric Renderer)
+
+React Native 执行的 React 框架代码,和 React 在 Web 中执行代码是同一份。但是,React Native 渲染的是通用平台视图(宿主视图)而不是 DOM 节点(可以认为 DOM 是 Web 的宿主视图)。 Fabric 渲染器使得渲染宿主视图变得可行。Fabric 让 React 与各个平台直接通信并管理其宿主视图实例。 Fabric 渲染器存在于 JavaScript 中,并且它调用的是由 C++ 代码暴露的接口。在这篇文章中有更多关于 React 渲染器的信息。
+
+## 宿主平台(Host platform)
+
+React Native 嵌入的平台,比如 Android、iOS、Windows、macOS。
+
+## 宿主视图树(Host View Tree)
+
+宿主视图树就是一系列的宿主视图。宿主平台有 Android 平台、iOS 平台等等。在 Android 上,宿主视图就是 android.view.ViewGroup实例、 android.widget.TextView实例等等。宿主视图就像积木一样地构成了宿主视图树。每个宿主视图的大小和坐标位置基于的是 LayoutMetrics,而 LayoutMetrics是通过布局引擎 Yoga 计算出来的。宿主视图的样式和内容信息,是从 React 影子树中得到的。
+
+## JavaScript Interfaces (JSI)
+
+一个轻量级的 API,给在 C++ 应用中嵌入的 JavaScript 引擎用的。Fabric 使用它在 Fabric 的 C++ 核心和 React 之间进行通信。
+
+## Java Native Interface (JNI)
+
+Java Native Interface (JNI):一个用 Java 写的 [API](https://docs.oracle.com/javase/8/docs/technotes/guides/jni/),用于在 Java 中写 native(译注:指调用 C++) 方法。作用是实现 Fabric 的 C++ 核心和 Android 的通信。
+
+## React 组件(React Component)
+
+React 组件就是 JavaScript 函数或者类,描述如何创建 React 元素。[Read more about React components, elements in this blog post.](https://reactjs.org/blog/2015/12/18/react-components-elements-and-instances.html)
+
+## React 复合组件(React Composite Components)
+
+React 组件的 render 方法中,包括其他 React 复合组件和 React 宿主组件。(译注:复合组件就是开发者声明的组件)
+
+## React 宿主组件(React Host Components or Host Components)
+
+React 组件的视图是通过宿主视图,比如 ``、``,实现的。在 Web 中,ReactDOM 的宿主组件就是 `
`标签、`
`标签代表的组件。
+
+## React 元素树(React Element Trees)
+
+React 元素树是通过 JavaScript 中的 React 创建的,该树由一系类 React 元素组成。一个 React 元素就是一个普通的 JavaScript 对象,它描述了应该在屏幕中展示什么。一个元素包括属性 props、样式 styles、子元素 children。React 元素分为两类:React 复合组件实例(React Composite Components)和 React 宿主组件(React Host Components)实例,并且它只存在于 JavaScript 中。
+
+## React 影子树(React Shadow Tree and React Shadow Node)
+
+React 影子树是通过 Fabric 渲染器创建的,树由一系列 React 影子节点组成。一个 React 影子节点是一个对象,代表一个已经挂载的 React 宿主组件,其包含的属性 props 来自 JavaScript。它也包括布局信息,比如坐标系 x、y,宽高 width、height。在新渲染器 Fabric 中,React 影子节点对象只存在于 C++ 中。而在老架构中,它存在于手机运行时的堆栈中,比如 Android 的 JVM。
+
+## Yoga 树(以及 Yoga 节点)
+
+The _Yoga Tree_ is used by [Yoga](https://yogalayout.com/) to calculate layout information for a React Shadow Tree. Each React Shadow Node typically creates a _Yoga Node_ because React Native employs Yoga to calculate layout. However, this is not a hard requirement. Fabric can also create React Shadow Nodes that do not use Yoga; the implementation of each React Shadow Node determines how to calculate layout.
diff --git a/cnwebsite/versioned_docs/version-0.75/handling-text-input.md b/cnwebsite/versioned_docs/version-0.75/handling-text-input.md
new file mode 100644
index 00000000000..6a61ad4ba1f
--- /dev/null
+++ b/cnwebsite/versioned_docs/version-0.75/handling-text-input.md
@@ -0,0 +1,38 @@
+---
+id: handling-text-input
+title: 处理文本输入
+---
+
+[`TextInput`](textinput#content)是一个允许用户输入文本的[基础组件](intro-react-native-components)。它有一个名为`onChangeText`的属性,此属性接受一个函数,而此函数会在文本变化时被调用。另外还有一个名为`onSubmitEditing`的属性,会在文本被提交后(用户按下软键盘上的提交键)调用。
+
+假如我们要实现当用户输入时,实时将其以单词为单位翻译为另一种文字。我们假设这另一种文字来自某个吃货星球,只有一个单词: 🍕。所以"Hello there Bob"将会被翻译为"🍕🍕🍕"。
+
+```SnackPlayer name=Handling%20Text%20Input
+import React, { useState } from 'react';
+import { Text, TextInput, View } from 'react-native';
+
+const PizzaTranslator = () => {
+ const [text, setText] = useState('');
+ return (
+
+ setText(text)}
+ defaultValue={text}
+ />
+
+ {text.split(' ').map((word) => word && '🍕').join(' ')}
+
+
+ );
+}
+
+export default PizzaTranslator;
+```
+
+在上面的例子里,我们把`text`保存到 state 中,因为它会随着时间变化。
+
+文本输入方面还有很多其他的东西要处理。比如你可能想要在用户输入的时候进行验证,在[React 中的受限组件](https://doc.react-china.org/docs/forms.html#%E5%8F%97%E6%8E%A7%E7%BB%84%E4%BB%B6)一节中有一些详细的示例(注意 react 中的 onChange 对应的是 rn 中的 onChangeText)。此外你还需要看看[TextInput 的文档](textinput.md)。
+
+TextInput 可能是天然具有“动态状态”的最简单的组件了。下面我们来看看另一类输入组件,先从[如何处理触摸开始学习](handling-touches.md)。
diff --git a/cnwebsite/versioned_docs/version-0.75/handling-touches.md b/cnwebsite/versioned_docs/version-0.75/handling-touches.md
new file mode 100644
index 00000000000..c74576d50f2
--- /dev/null
+++ b/cnwebsite/versioned_docs/version-0.75/handling-touches.md
@@ -0,0 +1,179 @@
+---
+id: handling-touches
+title: 处理触摸事件
+---
+
+移动应用上的用户交互基本靠“摸”。当然,“摸”也是有各种姿势的:在一个按钮上点击,在一个列表上滑动,或是在一个地图上缩放。React Native 提供了可以处理常见触摸手势(例如点击或滑动)的组件, 以及可用于识别更复杂的手势的完整的[手势响应系统](gesture-responder-system.md)。
+
+## 显示一个简单的按钮
+
+[Button](button.md)是一个简单的跨平台的按钮组件。下面是一个最简示例:
+
+```jsx
+ {
+ Alert.alert('你点击了按钮!');
+ }}
+ title="点我!"
+/>
+```
+
+上面这段代码会在 iOS 上渲染一个蓝色的标签状按钮,在 Android 上则会渲染一个蓝色圆角矩形带白字的按钮。点击这个按钮会调用"onPress"函数,具体作用就是显示一个 alert 弹出框。你还可以指定"color"属性来修改按钮的颜色。
+
+![](assets/Button.png)
+
+再试试下面这个使用`Button`的例子吧。你可以点击"Tap to Play"来预览真实效果。
+
+```SnackPlayer name=Button%20Basics
+import React, { Component } from 'react';
+import { Alert, Button, StyleSheet, View } from 'react-native';
+
+export default class ButtonBasics extends Component {
+ _onPressButton() {
+ Alert.alert('You tapped the button!')
+ }
+
+ render() {
+ return (
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+ }
+}
+
+const styles = StyleSheet.create({
+ container: {
+ flex: 1,
+ justifyContent: 'center',
+ },
+ buttonContainer: {
+ margin: 20
+ },
+ alternativeLayoutButtonContainer: {
+ margin: 20,
+ flexDirection: 'row',
+ justifyContent: 'space-between'
+ }
+})
+
+```
+
+## Touchable 系列组件
+
+这个组件的样式是固定的。所以如果它的外观并不怎么搭配你的设计,那就需要使用`TouchableOpacity`或是`TouchableNativeFeedback`组件来定制自己所需要的按钮,视频教程[如何制作一个按钮](http://v.youku.com/v_show/id_XMTQ5OTE3MjkzNg==.html?f=26822355&from=y1.7-1.3)讲述了完整的过程。或者你也可以在 github.com 网站上搜索 'react native button' 来看看社区其他人的作品。
+
+具体使用哪种组件,取决于你希望给用户什么样的视觉反馈:
+
+- 一般来说,你可以使用[**TouchableHighlight**](touchablehighlight.md)来制作按钮或者链接。注意此组件的背景会在用户手指按下时变暗。
+
+- 在 Android 上还可以使用[**TouchableNativeFeedback**](touchablenativefeedback.md),它会在用户手指按下时形成类似墨水涟漪的视觉效果。
+
+- [**TouchableOpacity**](touchableopacity.md)会在用户手指按下时降低按钮的透明度,而不会改变背景的颜色。
+
+- 如果你想在处理点击事件的同时不显示任何视觉反馈,则需要使用[**TouchableWithoutFeedback**](touchablewithoutfeedback.md)。
+
+某些场景中你可能需要检测用户是否进行了长按操作。可以在上面列出的任意组件中使用`onLongPress`属性来实现。
+
+我们来看一下示例:
+
+```SnackPlayer platform=android&name=Touchables
+import React, { Component } from 'react';
+import { Alert, Platform, StyleSheet, Text, TouchableHighlight, TouchableOpacity, TouchableNativeFeedback, TouchableWithoutFeedback, View } from 'react-native';
+
+export default class Touchables extends Component {
+ _onPressButton() {
+ Alert.alert('You tapped the button!')
+ }
+
+ _onLongPressButton() {
+ Alert.alert('You long-pressed the button!')
+ }
+
+
+ render() {
+ return (
+
+
+
+ TouchableHighlight
+
+
+
+
+ TouchableOpacity
+
+
+
+
+ TouchableNativeFeedback
+
+
+
+
+ TouchableWithoutFeedback
+
+
+
+
+ Touchable with Long Press
+
+
+
+ );
+ }
+}
+
+const styles = StyleSheet.create({
+ container: {
+ paddingTop: 60,
+ alignItems: 'center'
+ },
+ button: {
+ marginBottom: 30,
+ width: 260,
+ alignItems: 'center',
+ backgroundColor: '#2196F3'
+ },
+ buttonText: {
+ textAlign: 'center',
+ padding: 20,
+ color: 'white'
+ }
+})
+```
+
+## 在列表中上下滑动、在视图上左右滑动以及双指缩放
+
+另一个在移动应用中常见的手势就是滑动。用户会在列表中上下滑动,或是在视图上左右滑动。要处理这样的手势,你可以看一下[如何使用滚动视图](using-a-scrollview.md)这篇文档。
+
+## Known issues
+
+- [react-native#29308](https://github.com/facebook/react-native/issues/29308#issuecomment-792864162): The touch area never extends past the parent view bounds and on Android negative margin is not supported.
diff --git a/cnwebsite/versioned_docs/version-0.75/headless-js-android.md b/cnwebsite/versioned_docs/version-0.75/headless-js-android.md
new file mode 100644
index 00000000000..4eb80e92453
--- /dev/null
+++ b/cnwebsite/versioned_docs/version-0.75/headless-js-android.md
@@ -0,0 +1,392 @@
+---
+id: headless-js-android
+title: Headless JS(后台任务)
+---
+
+import Tabs from '@theme/Tabs'; import TabItem from '@theme/TabItem';
+import constants from '@site/core/TabsConstants';
+
+Headless JS 是一种使用 js 在后台执行任务的方法。它可以用来在后台同步数据、处理推送通知或是播放音乐等等。
+
+## JS 端的 API
+
+首先我们要通过`AppRegistry`来注册一个异步函数,这个函数我们称之为“任务”。注册方式类似在 index.js 中注册 RN 应用:
+
+```jsx
+import { AppRegistry } from 'react-native';
+AppRegistry.registerHeadlessTask('SomeTaskName', () =>
+ require('SomeTaskName')
+);
+```
+
+然后创建 require 中引用的`SomeTaskName.js`文件:
+
+```jsx
+module.exports = async taskData => {
+ // 要做的任务
+};
+```
+
+你可以在任务中处理任何事情(网络请求、定时器等等),但唯独**不要涉及用户界面**!在任务完成后(例如在 promise 中调用 resolve),RN 会进入一个“暂停”模式,直到有新任务需要执行或者是应用回到前台。
+
+## 原生端的 API
+
+没错,我们还需要一些原生代码,但是请放心并不麻烦。首先需要像下面这样继承`HeadlessJsTaskService`,然后覆盖`getTaskConfig`方法的实现:
+
+
+
+
+```java
+package com.your_application_name;
+
+import android.content.Intent;
+import android.os.Bundle;
+import com.facebook.react.HeadlessJsTaskService;
+import com.facebook.react.bridge.Arguments;
+import com.facebook.react.jstasks.HeadlessJsTaskConfig;
+import javax.annotation.Nullable;
+
+public class MyTaskService extends HeadlessJsTaskService {
+
+ @Override
+ protected @Nullable HeadlessJsTaskConfig getTaskConfig(Intent intent) {
+ Bundle extras = intent.getExtras();
+ if (extras != null) {
+ return new HeadlessJsTaskConfig(
+ "SomeTaskName",
+ Arguments.fromBundle(extras),
+ 5000, // timeout in milliseconds for the task
+ false // optional: defines whether or not the task is allowed in foreground. Default is false
+ );
+ }
+ return null;
+ }
+}
+```
+
+
+
+
+```kotlin
+package com.your_application_name;
+
+import android.content.Intent
+import com.facebook.react.HeadlessJsTaskService
+import com.facebook.react.bridge.Arguments
+import com.facebook.react.jstasks.HeadlessJsTaskConfig
+
+class MyTaskService : HeadlessJsTaskService() {
+ override fun getTaskConfig(intent: Intent): HeadlessJsTaskConfig? {
+ return intent.extras?.let {
+ HeadlessJsTaskConfig(
+ "SomeTaskName",
+ Arguments.fromBundle(it),
+ 5000, // timeout for the task
+ false // optional: defines whether or not the task is allowed in foreground.
+ // Default is false
+ )
+ }
+ }
+}
+
+```
+
+
+
+
+然后记得把服务添加到`AndroidManifest`文件里:
+
+```
+
+```
+
+好了,现在当你[启动服务时][0](例如一个周期性的任务或是响应一些系统事件/广播),JS 任务就会开始执行。例如:
+
+
+
+
+```java
+Intent service = new Intent(getApplicationContext(), MyTaskService.class);
+Bundle bundle = new Bundle();
+
+bundle.putString("foo", "bar");
+service.putExtras(bundle);
+
+getApplicationContext().startForegroundService(service);
+```
+
+
+
+
+```kotlin
+val service = Intent(applicationContext, MyTaskService::class.java)
+val bundle = Bundle()
+
+bundle.putString("foo", "bar")
+
+service.putExtras(bundle)
+
+applicationContext.startForegroundService(service)
+```
+
+
+
+
+## 重试
+
+默认情况下,无头 JS 任务不会执行任何重试。要想进行重试,您需要创建一个`HeadlessJsRetryPolicy`并抛出特定的`Error`。
+
+`LinearCountingRetryPolicy`是`HeadlessJsRetryPolicy`的一种实现,它允许您指定最大重试次数,并在每次尝试之间设置固定的延迟。如果您的需求不适合此策略,那么您可以轻松地实现自己的`HeadlessJsRetryPolicy`。这些策略只需作为额外的参数传递给`HeadlessJsTaskConfig`构造函数,例如,
+
+
+
+
+```java
+HeadlessJsRetryPolicy retryPolicy = new LinearCountingRetryPolicy(
+ 3, // Max number of retry attempts
+ 1000 // Delay between each retry attempt
+);
+
+return new HeadlessJsTaskConfig(
+ 'SomeTaskName',
+ Arguments.fromBundle(extras),
+ 5000,
+ false,
+ retryPolicy
+);
+```
+
+
+
+
+```kotlin
+val retryPolicy: HeadlessJsTaskRetryPolicy =
+ LinearCountingRetryPolicy(
+ 3, // Max number of retry attempts
+ 1000 // Delay between each retry attempt
+ )
+
+return HeadlessJsTaskConfig("SomeTaskName", Arguments.fromBundle(extras), 5000, false, retryPolicy)
+```
+
+
+
+
+仅当抛出特定错误时,才会进行重试尝试。在无头JS任务中,您可以导入错误并在需要重试尝试时抛出。
+
+例如:
+
+```jsx
+import {HeadlessJsTaskError} from 'HeadlessJsTask';
+module.exports = async (taskData) => {
+const condition = ...;
+if (!condition) {
+ throw new HeadlessJsTaskError();
+}
+};
+```
+
+如果你想让所有错误都导致重试尝试,你需要捕获它们并抛出上述错误。
+
+## 注意事项
+
+- 默认情况下,如果您尝试在应用程序处于前台时运行任务,您的应用程序将崩溃。 这是为了防止开发人员在任务中进行大量工作并降低 UI 速度。 您可以通过传递第四个布尔参数来控制此行为。
+- 如果您从 `BroadcastReceiver` 启动服务,请确保在从 `onReceive()` 返回之前调用 `HeadlessJsTaskService.acquireWakeLockNow()`。
+
+## 示例
+
+我们可以使用 Java API 来开启一个 service。首先你需要考虑好 Service 启动的时机,并据此实现相关逻辑。下面是一个使用 Service 来处理网络连接变化的简单范例。
+接下来的几行代码展示了如何在 Android Manifest 文件中注册一个Broadcast Receiver。
+
+```xml
+
+
+
+
+
+```
+
+这个 Broadcast Receiver 主要在 onReceive 函数中处理广播 Intent 。这是一个让你确认 App 是否在前台工作的绝佳时机。如果 App 当前不在前台工作,那么我们就可以开始准备我们用来启动 Service 的 Intent 了。额外提及一点:如果有信息需要传递给Service,可以使用 putExtra 方法把信息打包成 bundle携带。当然也可以不传递任何信息(但是,始终谨记 bundle 只能够承载那些 parcelable 的值)。在最后,Service 将获取到 wakelock 并启动起来。
+
+
+
+
+```java
+import android.app.ActivityManager;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.net.ConnectivityManager;
+import android.net.Network;
+import android.net.NetworkCapabilities;
+import android.net.NetworkInfo;
+import android.os.Build;
+
+import com.facebook.react.HeadlessJsTaskService;
+
+public class NetworkChangeReceiver extends BroadcastReceiver {
+
+ @Override
+ public void onReceive(final Context context, final Intent intent) {
+ /**
+ This part will be called every time network connection is changed
+ e.g. Connected -> Not Connected
+ **/
+ if (!isAppOnForeground((context))) {
+ /**
+ We will start our service and send extra info about
+ network connections
+ **/
+ boolean hasInternet = isNetworkAvailable(context);
+ Intent serviceIntent = new Intent(context, MyTaskService.class);
+ serviceIntent.putExtra("hasInternet", hasInternet);
+ context.startForegroundService(serviceIntent);
+ HeadlessJsTaskService.acquireWakeLockNow(context);
+ }
+ }
+
+ private boolean isAppOnForeground(Context context) {
+ /**
+ We need to check if app is in foreground otherwise the app will crash.
+ https://stackoverflow.com/questions/8489993/check-android-application-is-in-foreground-or-not
+ **/
+ ActivityManager activityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
+ List appProcesses =
+ activityManager.getRunningAppProcesses();
+ if (appProcesses == null) {
+ return false;
+ }
+ final String packageName = context.getPackageName();
+ for (ActivityManager.RunningAppProcessInfo appProcess : appProcesses) {
+ if (appProcess.importance ==
+ ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND &&
+ appProcess.processName.equals(packageName)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public static boolean isNetworkAvailable(Context context) {
+ ConnectivityManager cm = (ConnectivityManager)
+ context.getSystemService(Context.CONNECTIVITY_SERVICE);
+
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
+ Network networkCapabilities = cm.getActiveNetwork();
+
+ if(networkCapabilities == null) {
+ return false;
+ }
+
+ NetworkCapabilities actNw = cm.getNetworkCapabilities(networkCapabilities);
+
+ if(actNw == null) {
+ return false;
+ }
+
+ if(actNw.hasTransport(NetworkCapabilities.TRANSPORT_WIFI) || actNw.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR) || actNw.hasTransport(NetworkCapabilities.TRANSPORT_ETHERNET)) {
+ return true;
+ }
+
+ return false;
+ }
+
+ // deprecated in API level 29
+ NetworkInfo netInfo = cm.getActiveNetworkInfo();
+ return (netInfo != null && netInfo.isConnected());
+ }
+}
+```
+
+
+
+
+```kotlin
+import android.app.ActivityManager
+import android.app.ActivityManager.RunningAppProcessInfo
+import android.content.BroadcastReceiver
+import android.content.Context
+import android.content.Intent
+import android.net.ConnectivityManager
+import android.net.NetworkCapabilities
+import android.os.Build
+import com.facebook.react.HeadlessJsTaskService
+
+class NetworkChangeReceiver : BroadcastReceiver() {
+ override fun onReceive(context: Context, intent: Intent?) {
+ /**
+ * This part will be called every time network connection is changed e.g. Connected -> Not
+ * Connected
+ */
+ if (!isAppOnForeground(context)) {
+ /** We will start our service and send extra info about network connections */
+ val hasInternet = isNetworkAvailable(context)
+ val serviceIntent = Intent(context, MyTaskService::class.java)
+ serviceIntent.putExtra("hasInternet", hasInternet)
+ context.startForegroundService(serviceIntent)
+ HeadlessJsTaskService.acquireWakeLockNow(context)
+ }
+ }
+
+ private fun isAppOnForeground(context: Context): Boolean {
+ /**
+ * We need to check if app is in foreground otherwise the app will crash.
+ * https://stackoverflow.com/questions/8489993/check-android-application-is-in-foreground-or-not
+ */
+ val activityManager = context.getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager
+ val appProcesses = activityManager.runningAppProcesses ?: return false
+ val packageName: String = context.getPackageName()
+ for (appProcess in appProcesses) {
+ if (appProcess.importance == RunningAppProcessInfo.IMPORTANCE_FOREGROUND &&
+ appProcess.processName == packageName
+ ) {
+ return true
+ }
+ }
+ return false
+ }
+
+ companion object {
+ fun isNetworkAvailable(context: Context): Boolean {
+ val cm = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
+ var result = false
+
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
+ val networkCapabilities = cm.activeNetwork ?: return false
+
+ val actNw = cm.getNetworkCapabilities(networkCapabilities) ?: return false
+
+ result =
+ when {
+ actNw.hasTransport(NetworkCapabilities.TRANSPORT_WIFI) -> true
+ actNw.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR) -> true
+ actNw.hasTransport(NetworkCapabilities.TRANSPORT_ETHERNET) -> true
+ else -> false
+ }
+
+ return result
+ } else {
+ cm.run {
+ // deprecated in API level 29
+ cm.activeNetworkInfo?.run {
+ result =
+ when (type) {
+ ConnectivityManager.TYPE_WIFI -> true
+ ConnectivityManager.TYPE_MOBILE -> true
+ ConnectivityManager.TYPE_ETHERNET -> true
+ else -> false
+ }
+ }
+ }
+ }
+ return result
+ }
+ }
+}
+
+```
+
+
+
+
+[0]: https://developer.android.com/reference/android/content/Context.html#startService(android.content.Intent)
diff --git a/cnwebsite/versioned_docs/version-0.75/height-and-width.md b/cnwebsite/versioned_docs/version-0.75/height-and-width.md
new file mode 100644
index 00000000000..3cca45fee08
--- /dev/null
+++ b/cnwebsite/versioned_docs/version-0.75/height-and-width.md
@@ -0,0 +1,84 @@
+---
+id: height-and-width
+title: 高度与宽度
+---
+
+组件的高度和宽度决定了其在屏幕上显示的尺寸。
+
+## 指定宽高
+
+最简单的给组件设定尺寸的方式就是在样式中指定固定的`width`和`height`。React Native 中的尺寸都是无单位的,表示的是与设备像素密度无关的逻辑像素点。
+
+```SnackPlayer name=Height%20and%20Width
+import React from 'react';
+import { View } from 'react-native';
+
+const FixedDimensionsBasics = () => {
+ return (
+
+
+
+
+
+ );
+};
+
+export default FixedDimensionsBasics;
+```
+
+这样给组件设置尺寸也是一种常见的模式,比如要求在不同尺寸的屏幕上都显示成一样的大小。
+
+## 弹性(Flex)宽高
+
+在组件样式中使用`flex`可以使其在可利用的空间中动态地扩张或收缩。一般而言我们会使用`flex:1`来指定某个组件扩张以撑满所有剩余的空间。如果有多个并列的子组件使用了`flex:1`,则这些子组件会平分父容器中剩余的空间。如果这些并列的子组件的`flex`值不一样,则谁的值更大,谁占据剩余空间的比例就更大(即占据剩余空间的比等于并列组件间`flex`值的比)。
+
+> 组件能够撑满剩余空间的前提是其父容器的尺寸不为零。如果父容器既没有固定的`width`和`height`,也没有设定`flex`,则父容器的尺寸为零。其子组件如果使用了`flex`,也是无法显示的。
+
+```SnackPlayer name=Flex%20Dimensions
+import React from 'react';
+import { View } from 'react-native';
+
+const FlexDimensionsBasics = () => {
+ return (
+ // 试试去掉父View中的`flex: 1`。
+ // 则父View不再具有尺寸,因此子组件也无法再撑开。
+ // 然后再用`height: 300`来代替父View的`flex: 1`试试看?
+
+
+
+
+
+ );
+};
+
+export default FlexDimensionsBasics;
+```
+
+## 百分比宽高
+
+如果你想要按比例填充屏幕上某一部分,又不想使用 `flex` 布局,那么可以在组件的`style`中使用**百分比**。与弹性宽高相似,百分比宽高要求父容器有一个明确的尺寸。
+
+```SnackPlayer name=Percentage%20Dimensions
+import React from 'react';
+import { View } from 'react-native';
+const PercentageDimensionsBasics = () => {
+ // Try removing the `height: '100%'` on the parent View.
+ // The parent will not have dimensions, so the children can't expand.
+ return (
+
+
+
+
+
+ );
+};
+export default PercentageDimensionsBasics;
+```
+
+当你熟练掌握了如何控制组件的尺寸后,下一步可以[学习如何在屏幕上排列组件了](flexbox.md)。
diff --git a/cnwebsite/versioned_docs/version-0.75/hermes.md b/cnwebsite/versioned_docs/version-0.75/hermes.md
new file mode 100644
index 00000000000..785c0fe4733
--- /dev/null
+++ b/cnwebsite/versioned_docs/version-0.75/hermes.md
@@ -0,0 +1,181 @@
+---
+id: hermes
+title: 使用新的 Hermes 引擎
+---
+
+
+
+
+
+[Hermes](https://hermesengine.dev) 是专门针对 React Native 应用而优化的全新开源 JavaScript 引擎。对于很多应用来说,启用 Hermes 引擎可以优化启动时间,减少内存占用以及空间占用。从 React Native 0.70 版本开始 Hermes 已经默认启用,无需开发者再做任何配置。
+
+## Bundled Hermes
+
+React Native 自带一个**捆绑版本**的 Hermes。
+每当我们发布新版本的 React Native 时,我们都会为您构建一个 Hermes 版本。这将确保您使用的 Hermes 版本与您使用的 React Native 版本完全兼容。
+
+历史上,我们在将 Hermes 版本与 React Native 版本匹配方面遇到了问题。这完全消除了这个问题,并为用户提供了与特定 React Native 版本兼容的 JS 引擎。
+
+这个改变对 React Native 的用户来说是完全透明的。您仍然可以使用本页描述的命令禁用 Hermes。
+您可以[在此页面上阅读更多有关技术实现的信息](/architecture/bundled-hermes)。
+
+## 确认 Hermes 引擎是否启用
+
+如果您最近从头开始创建了一个新的应用程序,则可以在欢迎视图中查看是否启用了 Hermes:
+
+![在AwesomeProject中查看JS引擎状态的位置](/docs/assets/HermesApp.jpg)
+
+一个名为`HermesInternal`的全局变量将在 JavaScript 中可用,可用于验证是否正在使用 Hermes:
+
+```jsx
+const isHermes = () => !!global.HermesInternal;
+```
+
+:::caution 注意
+如果您使用了某种非标准的 JS bundle 加载方式,则可能会出现虽然`HermesInternal`变量存在,但并没有启用高度优化的预编译字节码的情况。请确认您正在使用`.hbc`文件,并按照以下详细说明进行测试前/测试后的性能比较。
+:::
+
+要了解 Hermes 的优势,请尝试编译应用的正式发布版本来进行测评。例如:
+
+```shell
+$ npx react-native run-android --variant release
+
+# or for iOS:
+$ npx react-native run-ios --configuration Release
+```
+
+这将在构建时将 JavaScript 编译为字节码,从而提高应用程序在设备上的启动速度。
+
+## 使用 Google Chrome 的 DevTools 来调试 Hermes 上的 JS
+
+Hermes 通过实现 Chrome 检查器协议来支持 Chrome 调试器。这意味着 Chrome 的工具可以直接在模拟器或实际物理设备上调试 Hermes 上运行的 JavaScript 代码。
+
+:::info 提示
+请注意,这与[调试](debugging#debugging-using-a-custom-javascript-debugger)文档部分中记录的应用内开发人员菜单中的“Remote JS Debugging”非常不同,后者实际上通过您的开发电脑上的 Chrome 的 V8 引擎来运行 JS 代码。
+:::
+
+Chrome 通过 Metro 连接到设备上运行的 Hermes,因此您需要知道 Metro 正在侦听的位置。通常这将在`localhost:8081`上,但这是[可配置的](https://facebook.github.io/metro/docs/configuration)。运行`yarn start`时,地址将在启动时写入 stdout。
+
+一旦您知道 Metro 服务器正在侦听的位置,就可以使用以下步骤使用 Chrome 进行连接:
+
+1. 在 Chrome 浏览器中导航到 `chrome://inspect`。
+
+2. 使用 `Configure...` 按钮添加 Metro 服务器地址(通常为 `localhost:8081`,如上所述)。
+
+![Chrome DevTools 设备页面中的 Configure 按钮](/docs/assets/HermesDebugChromeConfig.png)
+
+![添加 Chrome DevTools 网络目标的对话框](/docs/assets/HermesDebugChromeMetroAddress.png)
+
+3. 现在您应该看到一个名为 "Hermes React Native" 的目标,带有一个 "inspect" 链接,可以用来打开调试器。如果您没有看到 "inspect" 链接,请确保 Metro 服务器正在运行。![目标 inspect 链接](/docs/assets/HermesDebugChromeInspect.png)
+
+4. 现在您可以使用 Chrome 调试工具。例如,要在下次运行某些 JavaScript 时设置断点,请单击暂停按钮,并触发您的应用程序中会导致 JavaScript 执行的操作。![调试工具中的暂停按钮](/docs/assets/HermesDebugChromePause.png)
+
+## 在较早版本的 React Native 上启用 Hermes 引擎
+
+Hermes 从 React Native 0.70 版本开始默认启用。下面会介绍如何在较早版本的 React Native 上启用 Hermes 引擎。
+首先请确保你运行的 React Native 版本在 0.60.4 或以上。
+
+如果你现有的项目运行的是较老的版本,那么必须要先[升级](/docs/upgrading)。升级之后请先确保应用仍然能正常工作,再往下看如何切换到 Hermes 引擎。
+
+:::caution 关于兼容性的注意事项
+Hermes 的各个版本需要严格匹配 RN 的版本。请查看[Hermes 的发布日志](https://github.com/facebook/hermes/releases)来确定其兼容的版本。若版本不匹配会导致应用直接崩溃。
+:::
+
+:::caution 对于 Windows 用户的注意事项
+Hermes 需要 [Microsoft Visual C++ 2015 Redistributable](https://www.microsoft.com/en-us/download/details.aspx?id=48145)
+:::
+
+### Android
+
+编辑 `android/app/gradle.properties` 文件并修改`hermesEnabled`项为 true:
+
+```diff
+# 使用此属性启用或禁用 Hermes JS 引擎。
+# 如果设置为false,则将使用 JSC引擎。
+hermesEnabled=true
+```
+
+:::note 备注
+此属性自 React Native 0.71 版本开始才支持,如果在`gradle.properties` 文件中找不到,请在网站顶部导航条选择你当前的 React Native 版本,切换到那个版本的文档查看相应的操作。
+:::
+
+如果你使用 ProGuard,那么需要在 `proguard-rules.pro` 文件中添加如下规则:
+
+```
+-keep class com.facebook.hermes.unicode.** { *; }
+-keep class com.facebook.jni.** { *; }
+```
+
+如果在这之前已经编译过应用,那么需要清理下编译缓存:
+
+```shell
+$ cd android && ./gradlew clean
+```
+
+这样就完成了,然后可以正常编译并继续开发和部署了:
+
+```shell
+$ npx react-native run-android
+```
+
+:::note 备注 关于 Android App Bundles 格式的支持
+Android app bundles 格式从 react-native 0.62.0 版本开始支持。
+:::
+
+### iOS
+
+从 React Native 0.64 版本开始, Hermes 也支持在 iOS 上运行(且能够正常上架)。编辑`ios/Podfile`文件并做如下修改:
+
+```diff
+ use_react_native!(
+ :path => config[:reactNativePath],
+ # to enable hermes on iOS, change `false` to `true` and then install pods
+ # By default, Hermes is disabled on Old Architecture, and enabled on New Architecture.
+ # You can enable/disable it manually by replacing `flags[:hermes_enabled]` with `true` or `false`.
+- :hermes_enabled => flags[:hermes_enabled],
++ :hermes_enabled => true
+ )
+```
+
+默认情况下,如果您使用新架构,则将使用 Hermes。通过指定诸如`true`或`false`之类的值,您可以根据需要启用/禁用 Hermes。
+
+配置完成后,您可以使用以下命令安装 Hermes pods:
+
+```shell
+$ cd ios && pod install
+```
+
+就这样!您现在可以像往常一样开发和部署您的应用程序了:
+
+```shell
+$ npx react-native run-ios
+```
+
+## 切换回 JavaScriptCore 引擎
+
+React Native 也仍然支持使用 JavaScriptCore 作为[运行环境](javascript-environment)。请按以下说明进行切换。
+
+### Android
+
+编辑 `android/app/gradle.properties` 文件并修改`hermesEnabled`项为 false:
+
+```diff
+# Use this property to enable or disable the Hermes JS engine.
+# If set to false, you will be using JSC instead.
+hermesEnabled=false
+```
+
+### iOS
+
+编辑您的 `ios/Podfile` 文件并进行如下所示的更改:
+
+```diff
+ use_react_native!(
+ :path => config[:reactNativePath],
+ # Hermes is now enabled by default. Disable by setting this flag to false.
+ # Upcoming versions of React Native may rely on get_default_flags(), but
+ # we make it explicit here to aid in the React Native upgrade process.
+- :hermes_enabled => flags[:hermes_enabled],
++ :hermes_enabled => false,
+ )
+```
diff --git a/cnwebsite/versioned_docs/version-0.75/image-style-props.md b/cnwebsite/versioned_docs/version-0.75/image-style-props.md
new file mode 100644
index 00000000000..fa51a69ae68
--- /dev/null
+++ b/cnwebsite/versioned_docs/version-0.75/image-style-props.md
@@ -0,0 +1,389 @@
+---
+id: image-style-props
+title: 图片样式属性
+---
+
+
+## 示例
+
+### Image Resize Mode
+
+```SnackPlayer name=Image%20Resize%20Modes%20Example
+import React from 'react';
+import {View, Image, Text, StyleSheet} from 'react-native';
+
+const DisplayAnImageWithStyle = () => {
+ return (
+
+
+
+ resizeMode : cover
+
+
+
+ resizeMode : contain
+
+
+
+ resizeMode : stretch
+
+
+
+ resizeMode : repeat
+
+
+
+ resizeMode : center
+
+
+ );
+};
+
+const styles = StyleSheet.create({
+ container: {
+ display: 'flex',
+ flexDirection: 'column',
+ justifyContent: 'space-around',
+ alignItems: 'center',
+ height: '100%',
+ textAlign: 'center',
+ },
+});
+
+export default DisplayAnImageWithStyle;
+```
+
+### Image Border
+
+```SnackPlayer name=Style%20BorderWidth%20and%20BorderColor%20Example
+import React from 'react';
+import {View, Image, StyleSheet, Text} from 'react-native';
+
+const DisplayAnImageWithStyle = () => {
+ return (
+
+
+ borderColor & borderWidth
+
+ );
+};
+
+const styles = StyleSheet.create({
+ container: {
+ display: 'flex',
+ flexDirection: 'column',
+ justifyContent: 'center',
+ alignItems: 'center',
+ height: '100%',
+ textAlign: 'center',
+ },
+});
+
+export default DisplayAnImageWithStyle;
+```
+
+### Image Border Radius
+
+```SnackPlayer name=Style%20Border%20Radius%20Example
+import React from 'react';
+import {View, Image, StyleSheet, Text} from 'react-native';
+
+const DisplayAnImageWithStyle = () => {
+ return (
+
+
+
+ borderTopRightRadius
+
+
+
+ borderBottomRightRadius
+
+
+
+ borderBottomLeftRadius
+
+
+
+ borderTopLeftRadius
+
+
+ );
+};
+
+const styles = StyleSheet.create({
+ container: {
+ display: 'flex',
+ flexDirection: 'column',
+ justifyContent: 'space-around',
+ alignItems: 'center',
+ height: '100%',
+ textAlign: 'center',
+ },
+});
+
+export default DisplayAnImageWithStyle;
+```
+
+### Image Tint
+
+```SnackPlayer name=Style%20tintColor%20Function%20Component
+import React from 'react';
+import {View, Image, StyleSheet, Text} from 'react-native';
+
+const DisplayAnImageWithStyle = () => {
+ return (
+
+
+ tintColor
+
+ );
+};
+
+const styles = StyleSheet.create({
+ container: {
+ display: 'flex',
+ flexDirection: 'column',
+ justifyContent: 'center',
+ alignItems: 'center',
+ height: '100%',
+ textAlign: 'center',
+ },
+});
+
+export default DisplayAnImageWithStyle;
+```
+
+
+# 文档
+
+## Props
+
+### `backfaceVisibility`
+
+这个属性定义了一个旋转后的图像的背面是否应该可见。
+
+| 类型 | 默认值 |
+| ----------------------------- | ----------- |
+| enum(`'visible'`, `'hidden'`) | `'visible'` |
+
+---
+
+### `backgroundColor`
+
+| 类型 |
+| ------------------ |
+| [color](colors.md) |
+
+---
+
+### `borderBottomLeftRadius`
+
+| Type |
+| ------ |
+| number |
+
+---
+
+### `borderBottomRightRadius`
+
+| Type |
+| ------ |
+| number |
+
+---
+
+### `borderColor`
+
+| Type |
+| ------------------ |
+| [color](colors.md) |
+
+---
+
+### `borderRadius`
+
+| Type |
+| ------ |
+| number |
+
+---
+
+### `borderTopLeftRadius`
+
+| Type |
+| ------ |
+| number |
+
+---
+
+### `borderTopRightRadius`
+
+| Type |
+| ------ |
+| number |
+
+---
+
+### `borderWidth`
+
+| Type |
+| ------ |
+| number |
+
+---
+
+### `opacity`
+
+为图像设置不透明度值。该数字应该在 `0.0` 到 `1.0` 的范围内。
+
+| Type | Default |
+| ------ | ------- |
+| number | `1.0` |
+
+---
+
+### `overflow`
+
+| Type | Default |
+| ----------------------------- | ----------- |
+| enum(`'visible'`, `'hidden'`) | `'visible'` |
+
+---
+
+### `overlayColor`
| number | prefetch()返回的 id |
+
+---
+
+### `getSize()`
+
+```jsx
+Image.getSize(uri, success, [failure]);
+```
+
+在显示图片前获取图片的宽高(以像素为单位)。如果图片地址不正确或下载失败,此方法也会失败。
+
+要获取图片的尺寸,首先需要加载或下载图片(同时会被缓存起来)。这意味着理论上你可以用这个方法来预加载图片,虽然此方法并没有针对这一用法进行优化,而且将来可能会换一些实现方案使得并不需要完整下载图片即可获取尺寸。所以更好的预加载方案是使用下面那个专门的预加载方法。
+
+此方法不能用于静态图片资源。
+
+**参数:**
+
+| 名称 | 类型 | 必需 | 说明 |
+| ------- | -------- | ---- | -------------------------------- |
+| uri | string | 是 | 图片地址 |
+| success | function | 是 | 成功的回调函数,返回图片宽高数据 |
+| failure | function | 否 | 失败的回调函数 |
+
+---
+
+### `getSizeWithHeaders()`
+
+```jsx
+Image.getSizeWithHeaders(uri, headers, success, [failure]);
+```
+
+Retrieve the width and height (in pixels) of an image prior to displaying it with the ability to provide the headers for the request. This method can fail if the image cannot be found, or fails to download.
+
+In order to retrieve the image dimensions, the image may first need to be loaded or downloaded, after which it will be cached. This means that in principle you could use this method to preload images, however it is not optimized for that purpose, and may in future be implemented in a way that does not fully load/download the image data. A proper, supported way to preload images will be provided as a separate API.
+
+**参数:**
+
+| 名称 | 类型 | 必需 | 说明 |
+| ------- | -------- | ---- | ---------------------------------------------------------------------------------------------------- |
+| uri | string | 是 | 图片地址 |
+| headers | object | 是 | 请求的 headers |
+| success | function | 是 | The function that will be called if the image was successfully found and width and height retrieved. |
+| failure | function | 否 | The function that will be called if there was an error, such as failing toto retrieve the image. |
+
+---
+
+### `prefetch()`
+
+```jsx
+Image.prefetch(url);
+```
+
+预加载一个远程图片(将其下载到本地磁盘缓存)。
+
+**参数:**
+
+| 名称 | 类型 | 必需 | 说明 |
+| ---- | ------ | ---- | -------------- |
+| url | string | 是 | 图片的远程地址 |
+
+---
+
+### `queryCache()`
+
+```jsx
+Image.queryCache(urls);
+```
+
+查询图片缓存状态。根据图片 URL 地址返回缓存状态,比如"disk"(缓存在磁盘文件中)或是"memory"(缓存在内存中)。
+
+**参数:**
+
+| 名称 | 类型 | 必需 | 说明 |
+| ---- | ----- | ---- | ------------------------------- |
+| urls | array | 是 | 要查询缓存状态的图片 URL 数组。 |
+
+---
+
+### `resolveAssetSource()`
+
+```jsx
+Image.resolveAssetSource(source);
+```
+
+Resolves an asset reference into an object which has the properties `uri`, `width`, and `height`.
+
+**参数:**
+
+| 名称 | 类型 | 说明 |
+| ------------------------------------------------------- | ---------------------------------------- | ------------------------------------------------------------------------------ |
+| source
Required
| [ImageSource](image#imagesource), number | 静态图片引用语法`require('./image.jpg')`所返回的资源 id 或是一个`ImageSource`. |
+
+> `ImageSource`是一个对象,其结构为`{ uri: '' }`
+
+## 类型定义
+
+### ImageCacheEnum
iOS
+
+Enum which can be used to set the cache handling or stategy for the potentially cached responses.
+
+| Type | Default |
+| ------------------------------------------------------------------ | ----------- |
+| enum(`'default'`, `'reload'`, `'force-cache'`, `'only-if-cached'`) | `'default'` |
+
+- `default`: Use the native platforms default strategy.
+- `reload`: The data for the URL will be loaded from the originating source. No existing cache data should be used to satisfy a URL load request.
+- `force-cache`: The existing cached data will be used to satisfy the request, regardless of its age or expiration date. If there is no existing data in the cache corresponding the request, the data is loaded from the originating source.
+- `only-if-cached`: The existing cache data will be used to satisfy a request, regardless of its age or expiration date. If there is no existing data in the cache corresponding to a URL load request, no attempt is made to load the data from the originating source, and the load is considered to have failed.
+
+### ImageLoadEvent
+
+Object returned in the `onLoad` callback.
+
+| Name | Type | Description |
+| ------ | ------ | ----------------------------------- |
+| source | object | The [source object](#source-object) |
+
+#### Source Object
+
+**Properties:**
+
+| Name | Type | Description |
+| ------ | ------ | ------------------------------------------------------------ |
+| width | number | The width of loaded image. |
+| height | number | The height of loaded image. |
+| uri | string | A string representing the resource identifier for the image. |
+
+### ImageSource
+
+| Type |
+| -------------------------------- |
+| object, array of objects, number |
+
+**Properties (if passing as object or array of objects):**
+
+|
Name
| Type | Description |
+| -------------------------------------- | ------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
+| uri | string | A string representing the resource identifier for the image, which could be an http address, a local file path, or the name of a static image resource. |
+| width | number | Can be specified if known at build time, in which case the value will be used to set the default `` component dimension. |
+| height | number | Can be specified if known at build time, in which case the value will be used to set the default `` component dimension. |
+| scale | number | Used to indicate the scale factor of the image. Defaults to `1.0` if unspecified, meaning that one image pixel equates to one display point / DIP. |
+| bundle
iOS
| string | The iOS asset bundle which the image is included in. This will default to `[NSBundle mainBundle]` if not set. |
+| method | string | The HTTP Method to use. Defaults to `'GET'` if not specified. |
+| headers | object | An object representing the HTTP headers to send along with the request for a remote image. |
+| body | string | The HTTP body to send with the request. This must be a valid UTF-8 string, and will be sent exactly as specified, with no additional encoding (e.g. URL-escaping or base64) applied. |
+| cache
+
+如果你想在你的应用程序中启用 Deep Links,请遵循以下指南:
+
+
+
+
+> 要了解更多如何在 Android 上支持深度链接的说明,请参阅[Enabling Deep Links for App Content - Add Intent Filters for Your Deep Links](http://developer.android.com/training/app-indexing/deep-linking.html#adding-filters).
+
+如果要在现有的 MainActivity 中监听传入的 intent,那么需要在`AndroidManifest.xml`中将 MainActivity 的`launchMode`设置为`singleTask`。相关解释可参考[``](http://developer.android.com/guide/topics/manifest/activity-element.html)文档。
+
+```xml
+
+```
+
+
+
+
+> **注意:** 对于 iOS 来说,如果要在 App 启动后也监听传入的 App 链接,那么首先需要在项目中链接`RCTLinking`,具体步骤请参考[手动链接](linking-libraries-ios#手动链接)这篇文档,然后需要在`AppDelegate.m`中增加以下代码:
+
+```objectivec
+// iOS 9.x 或更高版本
+#import
+
+- (BOOL)application:(UIApplication *)application
+ openURL:(NSURL *)url
+ options:(NSDictionary *)options
+{
+ return [RCTLinkingManager application:application openURL:url options:options];
+}
+```
+
+```objectivec
+// iOS 8.x 或更低版本
+#import
+
+- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url
+ sourceApplication:(NSString *)sourceApplication annotation:(id)annotation
+{
+ return [RCTLinkingManager application:application openURL:url
+ sourceApplication:sourceApplication annotation:annotation];
+}
+```
+
+如果你的 app 用了 [Universal Links](https://developer.apple.com/library/prerelease/ios/documentation/General/Conceptual/AppSearch/UniversalLinks.html),需要正确的把下述代码添加进去:
+
+```objectivec
+- (BOOL)application:(UIApplication *)application continueUserActivity:(nonnull NSUserActivity *)userActivity
+ restorationHandler:(nonnull void (^)(NSArray> * _Nullable))restorationHandler
+{
+ return [RCTLinkingManager application:application
+ continueUserActivity:userActivity
+ restorationHandler:restorationHandler];
+}
+```
+
+
+
+
+### 处理 Deep Links
+
+有两种方法来处理打开应用程序的 URL。
+
+#### 1. 如果应用程序已经打开,应用程序就会出现在前台,并触发一个链接 'url' 事件
+
+你可以用 `Linking.addEventListener('url', callback)` 来处理这些事件——它使用链接的 URL 调用 `callback({ url })`
+
+#### 如果应用程序还没有打开,它就会被打开,并将 url 作为 initialURL 传入
+
+你可以用 `Linking.getInitialURL()` 来处理这些事件——它会返回一个解析到 URL 的 Promise (如果有的话)。
+
+---
+
+## 示例
+
+### Open Links and Deep Links (Universal Links)
+
+
+
+
+```SnackPlayer name=Linking%20Example&supportedPlatforms=ios,android&ext=js
+import React, {useCallback} from 'react';
+import {Alert, Button, Linking, StyleSheet, View} from 'react-native';
+
+const supportedURL = 'https://google.com';
+
+const unsupportedURL = 'slack://open?team=123456';
+
+const OpenURLButton = ({url, children}) => {
+ const handlePress = useCallback(async () => {
+ // Checking if the link is supported for links with custom URL scheme.
+ const supported = await Linking.canOpenURL(url);
+
+ if (supported) {
+ // Opening the link with some app, if the URL scheme is "http" the web link should be opened
+ // by some browser in the mobile
+ await Linking.openURL(url);
+ } else {
+ Alert.alert(`Don't know how to open this URL: ${url}`);
+ }
+ }, [url]);
+
+ return ;
+};
+
+const App = () => {
+ return (
+
+ Open Supported URL
+ Open Unsupported URL
+
+ );
+};
+
+const styles = StyleSheet.create({
+ container: {
+ flex: 1,
+ justifyContent: 'center',
+ alignItems: 'center',
+ },
+});
+
+export default App;
+```
+
+
+
+
+```SnackPlayer name=Linking%20Example&supportedPlatforms=ios,android&ext=tsx
+import React, {useCallback} from 'react';
+import {Alert, Button, Linking, StyleSheet, View} from 'react-native';
+
+const supportedURL = 'https://google.com';
+
+const unsupportedURL = 'slack://open?team=123456';
+
+type OpenURLButtonProps = {
+ url: string;
+ children: string;
+};
+
+const OpenURLButton = ({url, children}: OpenURLButtonProps) => {
+ const handlePress = useCallback(async () => {
+ // Checking if the link is supported for links with custom URL scheme.
+ const supported = await Linking.canOpenURL(url);
+
+ if (supported) {
+ // Opening the link with some app, if the URL scheme is "http" the web link should be opened
+ // by some browser in the mobile
+ await Linking.openURL(url);
+ } else {
+ Alert.alert(`Don't know how to open this URL: ${url}`);
+ }
+ }, [url]);
+
+ return ;
+};
+
+const App = () => {
+ return (
+
+ Open Supported URL
+ Open Unsupported URL
+
+ );
+};
+
+const styles = StyleSheet.create({
+ container: {
+ flex: 1,
+ justifyContent: 'center',
+ alignItems: 'center',
+ },
+});
+
+export default App;
+```
+
+
+
+
+### Open Custom Settings
+
+
+
+
+```SnackPlayer name=Linking%20Example&supportedPlatforms=ios,android&ext=js
+import React, {useCallback} from 'react';
+import {Button, Linking, StyleSheet, View} from 'react-native';
+
+const OpenSettingsButton = ({children}) => {
+ const handlePress = useCallback(async () => {
+ // Open the custom settings if the app has one
+ await Linking.openSettings();
+ }, []);
+
+ return ;
+};
+
+const App = () => {
+ return (
+
+ Open Settings
+
+ );
+};
+
+const styles = StyleSheet.create({
+ container: {
+ flex: 1,
+ justifyContent: 'center',
+ alignItems: 'center',
+ },
+});
+
+export default App;
+```
+
+
+
+
+```SnackPlayer name=Linking%20Example&supportedPlatforms=ios,android&ext=tsx
+import React, {useCallback} from 'react';
+import {Button, Linking, StyleSheet, View} from 'react-native';
+
+type OpenSettingsButtonProps = {
+ children: string;
+};
+
+const OpenSettingsButton = ({children}: OpenSettingsButtonProps) => {
+ const handlePress = useCallback(async () => {
+ // Open the custom settings if the app has one
+ await Linking.openSettings();
+ }, []);
+
+ return ;
+};
+
+const App = () => {
+ return (
+
+ Open Settings
+
+ );
+};
+
+const styles = StyleSheet.create({
+ container: {
+ flex: 1,
+ justifyContent: 'center',
+ alignItems: 'center',
+ },
+});
+
+export default App;
+```
+
+
+
+
+### 获取 Deep Link
+
+
+
+
+```SnackPlayer name=Linking%20Example&supportedPlatforms=ios,android&ext=js
+import React, {useState, useEffect} from 'react';
+import {Linking, StyleSheet, Text, View} from 'react-native';
+
+const useInitialURL = () => {
+ const [url, setUrl] = useState(null);
+ const [processing, setProcessing] = useState(true);
+
+ useEffect(() => {
+ const getUrlAsync = async () => {
+ // Get the deep link used to open the app
+ const initialUrl = await Linking.getInitialURL();
+
+ // The setTimeout is just for testing purpose
+ setTimeout(() => {
+ setUrl(initialUrl);
+ setProcessing(false);
+ }, 1000);
+ };
+
+ getUrlAsync();
+ }, []);
+
+ return {url, processing};
+};
+
+const App = () => {
+ const {url: initialUrl, processing} = useInitialURL();
+
+ return (
+
+
+ {processing
+ ? 'Processing the initial url from a deep link'
+ : `The deep link is: ${initialUrl || 'None'}`}
+
+
+ );
+};
+
+const styles = StyleSheet.create({
+ container: {
+ flex: 1,
+ justifyContent: 'center',
+ alignItems: 'center',
+ },
+});
+
+export default App;
+```
+
+
+
+
+```SnackPlayer name=Linking%20Example&supportedPlatforms=ios,android&ext=tsx
+import React, {useState, useEffect} from 'react';
+import {Linking, StyleSheet, Text, View} from 'react-native';
+
+const useInitialURL = () => {
+ const [url, setUrl] = useState(null);
+ const [processing, setProcessing] = useState(true);
+
+ useEffect(() => {
+ const getUrlAsync = async () => {
+ // Get the deep link used to open the app
+ const initialUrl = await Linking.getInitialURL();
+
+ // The setTimeout is just for testing purpose
+ setTimeout(() => {
+ setUrl(initialUrl);
+ setProcessing(false);
+ }, 1000);
+ };
+
+ getUrlAsync();
+ }, []);
+
+ return {url, processing};
+};
+
+const App = () => {
+ const {url: initialUrl, processing} = useInitialURL();
+
+ return (
+
+
+ {processing
+ ? 'Processing the initial url from a deep link'
+ : `The deep link is: ${initialUrl || 'None'}`}
+
+
+ );
+};
+
+const styles = StyleSheet.create({
+ container: {
+ flex: 1,
+ justifyContent: 'center',
+ alignItems: 'center',
+ },
+});
+
+export default App;
+```
+
+
+
+
+### 发送 Intents (Android)
+
+
+
+
+```SnackPlayer name=Linking%20Example&supportedPlatforms=android&ext=js
+import React, {useCallback} from 'react';
+import {Alert, Button, Linking, StyleSheet, View} from 'react-native';
+
+const SendIntentButton = ({action, extras, children}) => {
+ const handlePress = useCallback(async () => {
+ try {
+ await Linking.sendIntent(action, extras);
+ } catch (e) {
+ Alert.alert(e.message);
+ }
+ }, [action, extras]);
+
+ return ;
+};
+
+const App = () => {
+ return (
+
+
+ Power Usage Summary
+
+
+ App Notification Settings
+
+
+ );
+};
+
+const styles = StyleSheet.create({
+ container: {
+ flex: 1,
+ justifyContent: 'center',
+ alignItems: 'center',
+ },
+});
+
+export default App;
+```
+
+
+
+
+```SnackPlayer name=Linking%20Example&ext=tsx
+import React, {useCallback} from 'react';
+import {Alert, Button, Linking, StyleSheet, View} from 'react-native';
+
+type SendIntentButtonProps = {
+ action: string;
+ children: string;
+ extras?: Array<{
+ key: string;
+ value: string | number | boolean;
+ }>;
+};
+
+const SendIntentButton = ({
+ action,
+ extras,
+ children,
+}: SendIntentButtonProps) => {
+ const handlePress = useCallback(async () => {
+ try {
+ await Linking.sendIntent(action, extras);
+ } catch (e: any) {
+ Alert.alert(e.message);
+ }
+ }, [action, extras]);
+
+ return ;
+};
+
+const App = () => {
+ return (
+
+
+ Power Usage Summary
+
+
+ App Notification Settings
+
+
+ );
+};
+
+const styles = StyleSheet.create({
+ container: {
+ flex: 1,
+ justifyContent: 'center',
+ alignItems: 'center',
+ },
+});
+
+export default App;
+```
+
+
+
+
+# 文档
+
+## 方法
+
+### `addEventListener()`
+
+```tsx
+static addEventListener(
+ type: 'url',
+ handler: (event: {url: string}) => void,
+): EmitterSubscription;
+```
+
+通过监听 `url` 事件类型并提供处理程序,为链接更改添加处理程序。
+
+---
+
+### `canOpenURL()`
+
+```tsx
+static canOpenURL(url: string): Promise;
+```
+
+判断设备上是否有已经安装的应用可以处理指定的 URL。
+
+本方法会返回一个`Promise`对象。当确定传入的 URL 可以被处理时,promise 就会返回,值的第一个参数是表示是否可以打开 URL。
+
+The `Promise` will reject on Android if it was impossible to check if the URL can be opened or when targetting Android 11 (SDK 30) if you didn't specify the relevant intent queries in `AndroidManifest.xml`. Similarly on iOS, the promise will reject if you didn't add the specific scheme in the `LSApplicationQueriesSchemes` key inside `Info.plist` (see bellow).
+如果无法检查 URL 是否可以打开,或者当目标为 Android 11 (SDK 30) 平台且您没有在 `AndroidManifest.xml` 中指定相关的 intent queries,则 `Promise` 将在 Android 上拒绝。类似地,在 iOS 上,如果你没有在 `Info.plist` 中的 `LSApplicationQueriesSchemes` 键中添加特定的 scheme,`Promise` 将被拒绝(见下文)。
+
+**Parameters:**
+
+| Name | Type | Description |
+| -------------------------------------------------------- | ------ | ---------------- |
+| url
Required
| string | The URL to open. |
+
+> 对于 web 链接来说,协议头("http://", "https://")不能省略!
+
+> This method has limitations on iOS 9+. From [the official Apple documentation](https://developer.apple.com/documentation/uikit/uiapplication/1622952-canopenurl):
+>
+> - If your app is linked against an earlier version of iOS but is running in iOS 9.0 or later, you can call this method up to 50 times. After reaching that limit, subsequent calls always resolve to `false`. If the user reinstalls or upgrades the app, iOS resets the limit.
+>
+> 对于 iOS 9 来说,你需要在`Info.plist`中添加`LSApplicationQueriesSchemes`字段,否则`canOpenURL`可能一直返回 false。
+
+> When targeting Android 11 (SDK 30) you must specify the intents for the schemes you want to handle in `AndroidManifest.xml`. A list of common intents can be found [here](https://developer.android.com/guide/components/intents-common).
+>
+> For example to handle `https` schemes the following needs to be added to your manifest:
+>
+> ```
+>
+>
+>
+>
+>
+>
+>
+>
+> ```
+
+---
+
+### `getInitialURL()`
+
+```tsx
+static getInitialURL(): Promise;
+```
+
+If the app launch was triggered by an app link, it will give the link url, otherwise it will give `null`.
+
+> To support deep linking on Android, refer https://developer.android.com/training/app-indexing/deep-linking.html#handling-intents
+
+> getInitialURL may return `null` while debugging is enabled. Disable the debugger to ensure it gets passed.
+
+---
+
+### `openSettings()`
+
+```tsx
+static openSettings(): Promise;
+```
+
+Open the Settings app and displays the app’s custom settings, if it has any.
+
+---
+
+### `openURL()`
+
+```tsx
+static openURL(url: string): Promise;
+```
+
+Try to open the given `url` with any of the installed apps.
+
+You can use other URLs, like a location (e.g. "geo:37.484847,-122.148386" on Android or "https://maps.apple.com/?ll=37.484847,-122.148386" on iOS), a contact, or any other URL that can be opened with the installed apps.
+
+The method returns a `Promise` object. If the user confirms the open dialog or the url automatically opens, the promise is resolved. If the user cancels the open dialog or there are no registered applications for the url, the promise is rejected.
+
+**Parameters:**
+
+| Name | Type | Description |
+| -------------------------------------------------------- | ------ | ---------------- |
+| url
Required
| string | The URL to open. |
+
+> This method will fail if the system doesn't know how to open the specified URL. If you're passing in a non-http(s) URL, it's best to check `canOpenURL()` first.
+
+> For web URLs, the protocol (`"http://"`, `"https://"`) must be set accordingly!
+
+> This method may behave differently in a simulator e.g. `"tel:"` links are not able to be handled in the iOS simulator as there's no access to the dialer app.
+
+---
+
+### `sendIntent()`
+ The following section only applies to projects with native code exposed. If you are using the managed Expo workflow, see the guide on prebuild to use this API.
+
+
+
+## 访问控制台日志
+
+在运行 RN 应用时,可以在终端中运行如下命令来查看控制台的日志:
+
+```sh
+$ npx react-native log-ios
+$ npx react-native log-android
+```
+
+此外,你也可以在 iOS 模拟器的菜单中选择`Debug → Open System Log...`来查看。如果是 Android 应用,无论是运行在模拟器或是真机上,都可以通过在终端命令行里运行`adb logcat *:S ReactNative:V ReactNativeJS:V`命令来查看。
+
+:::info
+If you're using Expo CLI, console logs already appear in the same terminal output as the bundler.
+:::
+
+## 调试原生代码
+
+在和原生代码打交道时(比如编写原生模块),可以直接从 Android Studio 或是 Xcode 中启动应用,并利用这些 IDE 的内置功能来调试(比如设置断点)。这一方面和开发原生应用并无二致。
diff --git a/cnwebsite/versioned_docs/version-0.75/native-module-setup.md b/cnwebsite/versioned_docs/version-0.75/native-module-setup.md
new file mode 100644
index 00000000000..dab081dded5
--- /dev/null
+++ b/cnwebsite/versioned_docs/version-0.75/native-module-setup.md
@@ -0,0 +1,35 @@
+---
+id: native-modules-setup
+title: 原生模块配置
+---
+
+import NativeDeprecated from './the-new-architecture/\_markdown_native_deprecation.mdx'
+
+
+
+原生模块通常作为 npm 包分发,除了常规的 JavaScript 外,它们还会包含每个平台的一些本地代码。要了解更多关于 npm 包的信息,你可能会发现[这个指南](https://docs.npmjs.com/packages-and-modules/contributing-packages-to-the-registry)很有用。
+
+为了设置一个原生模块的基本项目结构,我们将使用社区工具[Bob](https://github.com/react-native-community/bob)。你可以继续深入了解该库的工作原理,但对于我们的需求,我们只需要执行基本的`create`脚本:
+
+```sh
+npx @react-native-community/bob create react-native-awesome-module
+```
+
+`react-native-awesome-module` 是您希望为新模块命名的名称。完成此操作后,在终端进入到 `react-native-awesome-module` 文件夹,并运行以下命令来引导示例项目:
+
+```sh
+yarn bootstrap
+```
+
+当引导完成后,您可以通过执行以下任一命令启动示例应用程序:
+
+```sh
+# Android app
+yarn example android
+# iOS app
+yarn example ios
+```
+
+当完成上述所有步骤后,您将能够继续使用 [Android Native Modules](native-modules-android) 或 [iOS Native Modules](native-modules-ios) 指南来添加一些代码。
+
+> 想要一个不那么主观的设置?可查看第三方工具 [create-react-native-module](https://github.com/brodybits/create-react-native-module)。
diff --git a/cnwebsite/versioned_docs/version-0.75/native-modules-android.md b/cnwebsite/versioned_docs/version-0.75/native-modules-android.md
new file mode 100644
index 00000000000..bcf0cf68a05
--- /dev/null
+++ b/cnwebsite/versioned_docs/version-0.75/native-modules-android.md
@@ -0,0 +1,1179 @@
+---
+id: native-modules-android
+title: Android 原生模块
+---
+
+import NativeDeprecated from './the-new-architecture/\_markdown_native_deprecation.mdx'
+import Tabs from '@theme/Tabs'; import TabItem from '@theme/TabItem'; import constants from '@site/core/TabsConstants';
+
+
+
+欢迎来到 Android 的原生模块。请先阅读 [原生模块简介](native-modules-intro) 以了解原生模块的基本概念。
+
+## 创建一个 Calendar 原生模块
+
+在以下指南中,你将创建一个名为 `CalendarModule` 的原生模块,它允许你从 JavaScript 访问 Android 的日历 API。最终,你将能够从 JavaScript 中调用 `CalendarModule.createCalendarEvent('Dinner Party', 'My House');`,从而调用 Java/Kotlin 方法创建一个日历事件。
+
+### 设置
+
+要开始,请在 Android Studio 中打开 React Native 应用程序中的 Android 项目。你可以在 React Native 应用中找到 Android 项目的位置:
+
+
+
+我们建议使用 Android Studio 来编写你的原生代码。Android Studio 是一个为 Android 开发而构建的 IDE,使用它将帮助你快速解决代码语法错误等小问题。
+
+我们还建议启用 [Gradle Daemon](https://docs.gradle.org/2.9/userguide/gradle_daemon.html) 以加快你迭代 Java/Kotlin 代码时的构建速度。
+
+### 创建自定义原生模块文件
+
+第一步是在 `android/app/src/main/java/com/your-app-name/` 文件夹中创建 Java/Kotlin 文件(`CalendarModule.java` 或 `CalendarModule.kt`)。该 Java/Kotlin 文件将包含您的原生模块 Java/Kotlin 类。
+
+
+
+然后添加如下代码:
+
+
+
+
+```java
+package com.your-apps-package-name; // replace your-apps-package-name with your app’s package name
+import com.facebook.react.bridge.NativeModule;
+import com.facebook.react.bridge.ReactApplicationContext;
+import com.facebook.react.bridge.ReactContext;
+import com.facebook.react.bridge.ReactContextBaseJavaModule;
+import com.facebook.react.bridge.ReactMethod;
+import java.util.Map;
+import java.util.HashMap;
+
+public class CalendarModule extends ReactContextBaseJavaModule {
+ CalendarModule(ReactApplicationContext context) {
+ super(context);
+ }
+}
+```
+
+
+
+
+```kotlin
+package com.your-apps-package-name; // replace your-apps-package-name with your app’s package name
+import com.facebook.react.bridge.NativeModule
+import com.facebook.react.bridge.ReactApplicationContext
+import com.facebook.react.bridge.ReactContext
+import com.facebook.react.bridge.ReactContextBaseJavaModule
+import com.facebook.react.bridge.ReactMethod
+
+class CalendarModule(reactContext: ReactApplicationContext) : ReactContextBaseJavaModule(reactContext) {...}
+```
+
+
+
+
+正如您所看到的,您的`CalendarModule`类继承自`ReactContextBaseJavaModule`类。对于安卓系统,Java/Kotlin 原生模块是用扩展了`ReactContextBaseJavaModule`并实现了 JavaScript 所需功能的类来编写的。
+
+值得注意的是,从技术上讲,Java/Kotlin 类只需要扩展`BaseJavaModule`类或实现`NativeModule`接口,才能被 React Native 视为原生模块。
+
+然而,我们建议您使用上面所示的`ReactContextBaseJavaModule`。`ReactContextBaseJavaModule`提供了`ReactApplicationContext`(RAC)的访问权限,这对于需要挂钩到活动生命周期方法的原生模块非常有用。使用`ReactContextBaseJavaModule`也将使您更容易在将来实现原生模块的类型安全性。为了实现原生模块类型安全性(将在未来版本中推出),React Native 会查看每个原生模块的 JavaScript 规范,并生成一个抽象基类,该基类扩展自`ReactContextBaseJavaModule`。
+
+### 模块名称
+
+所有 Android 平台上的 Java/Kotlin 原生模块都需要实现 `getName()` 方法。该方法返回一个字符串,代表了原生模块的名称。这样,原生模块就可以通过其名称在 JavaScript 中被访问。例如,在下面的代码片段中,`getName()` 返回 `"CalendarModule"`。
+
+
+
+
+```java
+// add to CalendarModule.java
+@Override
+public String getName() {
+ return "CalendarModule";
+}
+```
+
+
+
+
+```kotlin
+// add to CalendarModule.kt
+override fun getName() = "CalendarModule"
+```
+
+
+
+
+可以通过以下方式在 JS 中访问原生模块:
+
+```tsx
+const {CalendarModule} = ReactNative.NativeModules;
+```
+
+### 向 JavaScript 导出原生方法
+
+接下来,您需要在原生模块中添加一个方法,该方法可以创建日历事件,并可以在 JavaScript 中调用。所有打算从 JavaScript 调用的原生模块方法都必须使用`@ReactMethod`进行注解。
+
+为`CalendarModule`设置一个方法`createCalendarEvent()`,可以通过`CalendarModule.createCalendarEvent()`在 JS 中调用。目前,该方法将采用名称和位置作为字符串参数。参数类型选项将在稍后介绍。
+
+
+
+
+```java
+@ReactMethod
+public void createCalendarEvent(String name, String location) {
+}
+```
+
+
+
+
+```kotlin
+@ReactMethod fun createCalendarEvent(name: String, location: String) {}
+```
+
+
+
+
+在您从应用程序调用该方法时,请在该方法中添加一条调试日志以确认它已被调用。以下是如何从 Android 工具包中导入并使用[Log](https:// developer.android.com/reference/android/util/Log)类的示例:
+
+
+
+
+```java
+import android.util.Log;
+
+@ReactMethod
+public void createCalendarEvent(String name, String location) {
+ Log.d("CalendarModule", "Create event called with name: " + name
+ + " and location: " + location);
+}
+```
+
+
+
+
+```kotlin
+import android.util.Log
+
+@ReactMethod
+fun createCalendarEvent(name: String, location: String) {
+ Log.d("CalendarModule", "Create event called with name: $name and location: $location")
+}
+```
+
+
+
+
+一旦您完成了原生模块的实现并将其与 JavaScript 连接起来,您便可以遵循[这些步骤](https://developer.android.com/studio/debug/am-logcat.html)查看应用程序的日志。
+
+### 同步方法
+
+您可以将 `isBlockingSynchronousMethod = true` 传递给原生方法,将其标记为同步方法。
+
+
+
+
+```java
+@ReactMethod(isBlockingSynchronousMethod = true)
+```
+
+
+
+
+```kotlin
+@ReactMethod(isBlockingSynchronousMethod = true)
+```
+
+
+
+
+就目前而言,我们并不建议这么做,因为以同步的方式调用方法可能会带来严重的性能损失,并且可能会给你的原生模块引入与线程相关的 bug。此外,请注意,如果你选择启用 `isBlockingSynchronousMethod`, 你的应用程序将无法再使用 Google Chrome 调试器。这是因为同步方法需要 JS VM 与应用程序共享内存。对于 Google Chrome 调试器而言,React Native 运行在 Google Chrome 中的 JS VM 内部,并通过 WebSockets 与移动设备进行异步通信。
+
+### 在 Android 上注册模块
+
+一旦编写了原生模块,就需要将其注册到 React Native 中。为此,你需要将你的原生模块添加到一个 `ReactPackage` 中,并将该 `ReactPackage` 注册到 React Native。在初始化过程中,React Native 会遍历所有包,并对于每个 `ReactPackage`,注册其中的每个原生模块。
+
+React Native 会调用 `ReactPackage` 的 `createNativeModules()` 方法,以获取要注册的原生模块列表。对于 Android 而言,如果一个模块未在 createNativeModules 中被实例化并返回,那么它就不会在 JavaScript 中可用。
+
+要将你的原生模块添加到 `ReactPackage` 中,首先在 `android/app/src/main/java/com/your-app-name/` 文件夹中创建一个新的 Java/Kotlin 类(`MyAppPackage.java` 或 `MyAppPackage.kt`),并实现 `ReactPackage` 接口:
+
+然后添加以下内容:
+
+
+
+
+```java
+package com.your-app-name; // replace your-app-name with your app’s name
+import com.facebook.react.ReactPackage;
+import com.facebook.react.bridge.NativeModule;
+import com.facebook.react.bridge.ReactApplicationContext;
+import com.facebook.react.uimanager.ViewManager;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+public class MyAppPackage implements ReactPackage {
+
+ @Override
+ public List createViewManagers(ReactApplicationContext reactContext) {
+ return Collections.emptyList();
+ }
+
+ @Override
+ public List createNativeModules(
+ ReactApplicationContext reactContext) {
+ List modules = new ArrayList<>();
+
+ modules.add(new CalendarModule(reactContext));
+
+ return modules;
+ }
+
+}
+```
+
+
+
+
+```kotlin
+package com.your-app-name // replace your-app-name with your app’s name
+
+import android.view.View
+import com.facebook.react.ReactPackage
+import com.facebook.react.bridge.NativeModule
+import com.facebook.react.bridge.ReactApplicationContext
+import com.facebook.react.uimanager.ReactShadowNode
+import com.facebook.react.uimanager.ViewManager
+
+class MyAppPackage : ReactPackage {
+
+ override fun createViewManagers(
+ reactContext: ReactApplicationContext
+ ): MutableList>> = mutableListOf()
+
+ override fun createNativeModules(
+ reactContext: ReactApplicationContext
+ ): MutableList = listOf(CalendarModule(reactContext)).toMutableList()
+}
+```
+
+
+
+
+这个文件导入了你创建的原生模块`CalendarModule`。然后在`createNativeModules()`函数中实例化了`CalendarModule`并将其作为`NativeModules`列表返回以便注册。如果将来你添加更多原生模块,也可以在这里实例化它们并添加到返回的列表中。
+
+值得注意的是,这种注册原生模块的方式会在应用启动时主动地初始化所有原生模块,从而增加了应用的启动时间。你可以使用[TurboReactPackage](https://github.com/facebook/react-native/blob/main/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/TurboReactPackage.java)作为替代方案。与返回已实例化的原生模块对象列表的`createNativeModules`不同,TurboReactPackage 实现了一个`getModule(String name, ReactApplicationContext rac)`方法,在需要时创建原生模块对象。目前实现 TurboReactPackage 有点复杂。除了实现`getModule()`方法外,你还必须实现一个`getReactModuleInfoProvider()`方法,该方法返回包可实例化的所有原生模块列表以及实例化它们的函数,示例[在此](https://github.com/facebook/react-native/blob/8ac467c51b94c82d81930b4802b2978c85539925/ReactAndroid/src/main/java/com/facebook/react/CoreModulesPackage.java#L86-L165)。再次说明,使用 TurboReactPackage 将使你的应用拥有更快的启动时间,但目前编写起来有些麻烦。所以如果你选择使用 TurboReactPackage,请小心谨慎。
+
+要注册`CalendarModule`包,你必须将`MyAppPackage`添加到 ReactNativeHost 的`getPackages()`方法返回的包列表中。打开`MainApplication.java`或`MainApplication.kt`文件,位于如下路径:`android/app/src/main/java/com/your-app-name/`。
+
+找到 ReactNativeHost 的`getPackages()`方法,并将你的包添加到`getPackages()`返回的包列表中。
+
+
+
+
+```java
+@Override
+ protected List getPackages() {
+ @SuppressWarnings("UnnecessaryLocalVariable")
+ List packages = new PackageList(this).getPackages();
+ // below MyAppPackage is added to the list of packages returned
+ packages.add(new MyAppPackage());
+ return packages;
+ }
+```
+
+
+
+
+```kotlin
+override fun getPackages(): List =
+ PackageList(this).packages.apply {
+ // Packages that cannot be autolinked yet can be added manually here, for example:
+ // packages.add(new MyReactNativePackage());
+ add(MyAppPackage())
+ }
+```
+
+
+
+
+您已成功为 Android 注册了原生模块!
+
+### 测试已构建的内容
+
+此时,您已为 Android 原生模块搭建了基本的脚手架。通过在 JavaScript 中访问原生模块并调用它导出的方法来测试一下。
+
+在应用中找到一个添加调用原生模块的 createCalendarEvent()方法的位置。下面是一个示例组件 NewModuleButton,您可以在应用中添加它。您可以在 NewModuleButton 的 onPress()函数中调用原生模块。
+
+```tsx
+import React from 'react';
+import {NativeModules, Button} from 'react-native';
+
+const NewModuleButton = () => {
+ const onPress = () => {
+ console.log('We will invoke the native module here!');
+ };
+
+ return (
+
+ );
+};
+
+export default NewModuleButton;
+```
+
+为了从 JavaScript 访问您的原生模块,您需要先从 React Native 导入`NativeModules`:
+
+```tsx
+import {NativeModules} from 'react-native';
+```
+
+然后您就可以从`NativeModules`访问`CalendarModule`原生模块了。
+
+```tsx
+const {CalendarModule} = NativeModules;
+```
+
+现在您有了可用的 CalendarModule 原生模块,就可以调用您的原生方法`createCalendarEvent()`了。下面是在`NewModuleButton`的`onPress()`方法中添加的代码:
+
+```tsx
+const onPress = () => {
+ CalendarModule.createCalendarEvent('testName', 'testLocation');
+};
+```
+
+最后一步是重新构建 React Native 应用程序,以便您可以使用最新的原生代码(包括您新的原生模块!)。在您的 react native 应用程序所在的命令行中,运行以下命令:
+
+
+
+
+```shell
+npm run android
+```
+
+
+
+
+```shell
+yarn android
+```
+
+
+
+
+### 在迭代过程中构建
+
+在学习这些指南并对您的原生模块进行迭代的过程中,您需要对应用程序进行原生重建,以从 JavaScript 访问您最新的更改。这是因为您编写的代码位于应用程序的原生部分。虽然 React Native 的 metro bundler 可以监视 JavaScript 中的更改并为您实时重建,但它不会对原生代码进行操作。因此,如果您想测试最新的原生更改,需要使用上述命令进行重建。
+
+### 小结 ✨
+
+现在,您应该能够在应用程序中调用原生模块上的`createCalendarEvent()`方法。在我们的示例中,这是通过按下`NewModuleButton`来实现的。您可以通过查看在`createCalendarEvent()`方法中设置的日志来确认这一点。您可以按照[这些步骤](https://developer.android.com/studio/debug/am-logcat.html)在应用中查看 ADB 日志。然后,您应该能够搜索您的`Log.d`消息(在我们的示例中是"Create event called with name: testName and location: testLocation"),并在每次调用原生模块方法时看到您的消息被记录。
+
+
+
+在这一点上,您已经创建了一个 Android 原生模块,并从您的 React Native 应用程序中的 JavaScript 调用了它的原生方法。您可以继续学习诸如原生模块方法可用的参数类型以及如何设置回调和承诺之类的内容。
+
+## 超越日历原生模块
+
+### 更好的原生模块导出
+
+从上面的 `NativeModules` 导入您的原生模块是有点麻烦的。
+
+为了让您原生模块的消费者无需每次都这样访问您的原生模块,您可以为该模块创建一个 JavaScript 包装器。创建一个名为 `CalendarModule.js` 的新 JavaScript 文件,其中包含以下内容:
+
+```tsx
+/**
+* 这将原生 CalendarModule 模块作为 JS 模块暴露。它有一个名为 'createCalendarEvent' 的函数,该函数接受以下参数:
+
+* 1. String name: 表示事件名称的字符串
+* 2. String location: 表示事件位置的字符串
+*/
+import {NativeModules} from 'react-native';
+const {CalendarModule} = NativeModules;
+export default CalendarModule;
+```
+
+此 JavaScript 文件也将成为您添加任何 JavaScript 端功能的绝佳位置。例如,如果您使用 TypeScript 等类型系统,可以在此处为您的原生模块添加类型注释。虽然 React Native 目前还不支持从原生到 JS 的类型安全性,但您所有的 JS 代码都将是类型安全的。这样做也将使您将来更容易切换到类型安全的原生模块。下面是为 CalendarModule 添加类型安全性的示例:
+
+```tsx
+/**
+ * 这个模块以 JS 模块的方式暴露了原生 CalendarModule。它有一个名为 "createCalendarEvent" 的函数,接受以下两个参数:
+ *
+ * 1. String name: 代表事件名称的字符串
+ * 2. String location: 代表事件地点的字符串
+ */
+import {NativeModules} from 'react-native';
+const {CalendarModule} = NativeModules;
+interface CalendarInterface {
+ createCalendarEvent(name: string, location: string): void;
+}
+export default CalendarModule as CalendarInterface;
+```
+
+在其他 JavaScript 文件中,你可以如下引入原生模块并调用它的方法:
+
+```tsx
+import CalendarModule from './CalendarModule';
+CalendarModule.createCalendarEvent('foo', 'bar');
+```
+
+> 这假设你导入 `CalendarModule` 的位置与 `CalendarModule.js` 在同一层级目录。如有必要,请相应更新导入路径。
+
+### 参数类型
+
+当在 JavaScript 中调用原生模块方法时,React Native 会将参数从 JS 对象转换为对应的 Java/Kotlin 对象类型。例如,如果你的 Java 原生模块方法接受一个 double 类型,在 JS 中你需要用数字来调用该方法。React Native 会为你处理转换。下面列出了原生模块方法支持的参数类型以及它们在 JavaScript 中对应的等价类型。
+
+| Java | Kotlin | JavaScript |
+| ------------- | ------------- | ---------- |
+| Boolean | Boolean | ?boolean |
+| boolean | | boolean |
+| Double | Double | ?number |
+| double | | number |
+| String | String | string |
+| Callback | Callback | Function |
+| Promise | Promise | Promise |
+| ReadableMap | ReadableMap | Object |
+| ReadableArray | ReadableArray | Array |
+
+> 以下类型目前虽然受支持,但在 TurboModules 中将不再支持,请避免使用:
+>
+> - Integer Java/Kotlin -> ?number
+> - Float Java/Kotlin -> ?number
+> - int Java -> number
+> - float Java -> number
+
+对于上面未列出的参数类型,你需要自行处理类型转换。例如,在 Android 中,Date 类型的转换并不是开箱即用的。你可以在原生方法中自己处理 Date 类型的转换,如下所示:
+
+
+
+
+```java
+ String dateFormat = "yyyy-MM-dd";
+ SimpleDateFormat sdf = new SimpleDateFormat(dateFormat);
+ Calendar eStartDate = Calendar.getInstance();
+ try {
+ eStartDate.setTime(sdf.parse(startDate));
+ }
+
+```
+
+
+
+
+```kotlin
+ val dateFormat = "yyyy-MM-dd"
+ val sdf = SimpleDateFormat(dateFormat, Locale.US)
+ val eStartDate = Calendar.getInstance()
+ try {
+ sdf.parse(startDate)?.let {
+ eStartDate.time = it
+ }
+ }
+```
+
+
+
+
+### 导出常量
+
+一个原生模块可以通过实现在 JavaScript 中可用的原生方法 `getConstants()` 来导出常量。接下来,您将实现 `getConstants()` 并返回一个包含 `DEFAULT_EVENT_NAME` 常量的映射,您可以在 JavaScript 中访问该常量:
+
+
+
+
+```java
+@Override
+public Map getConstants() {
+ final Map constants = new HashMap<>();
+ constants.put("DEFAULT_EVENT_NAME", "New Event");
+ return constants;
+}
+```
+
+
+
+
+```kotlin
+override fun getConstants(): MutableMap =
+ hashMapOf("DEFAULT_EVENT_NAME" to "New Event")
+```
+
+
+
+
+然后,可以在 JS 中通过在原生模块上调用`getConstants`来访问该常量:
+
+```tsx
+const {DEFAULT_EVENT_NAME} = CalendarModule.getConstants();
+console.log(DEFAULT_EVENT_NAME);
+```
+
+理论上可以直接从原生模块对象访问在`getConstants()`中导出的常量。但这种做法将来不再受支持,因此我们鼓励社区转而采用上述方式,以避免将来不得不迁移代码。
+
+> 目前,常量仅在初始化时导出,因此如果您在运行时更改了 getConstants 的值,它不会影响 JavaScript 环境。这种情况将随着 Turbomodules 而改变。使用 Turbomodules 后,`getConstants()`将成为一个常规的原生模块方法,每次调用都会触及原生端。
+
+### 回调函数
+
+原生模块还支持一种独特的参数类型:回调函数。回调函数用于将数据从 Java/Kotlin 异步传递到 JavaScript,同时也可用于从原生端异步执行 JavaScript 代码。
+
+为了在原生模块方法中加入回调函数,首先要引入`Callback`接口,然后将`Callback`类型的参数添加到你的原生模块方法中。目前使用回调参数还有一些细微差别,不过这些将在 TurboModules 中得到解决。目前,你的函数参数只能有两个回调函数——一个成功回调和一个失败回调。另外,如果原生模块方法调用的最后一个参数是函数,则将被视为成功回调;如果倒数第二个参数是函数,则被视为失败回调。
+
+
+
+
+```java
+import com.facebook.react.bridge.Callback;
+
+@ReactMethod
+public void createCalendarEvent(String name, String location, Callback callBack) {
+}
+```
+
+
+
+
+```kotlin
+import com.facebook.react.bridge.Callback
+
+@ReactMethod fun createCalendarEvent(name: String, location: String, callback: Callback) {}
+```
+
+
+
+
+你可以在 Java/Kotlin 方法中调用回调函数,提供任何需要传递给 JavaScript 的数据。请注意,你只能从原生代码传递可序列化的数据到 JavaScript。如果需要传递原生对象,你可以使用`WriteableMaps`,如果需要使用集合,可以使用`WritableArrays`。还需要强调的是,回调函数不会在原生函数完成后立即被调用。下面是之前创建的一个事件 ID,将被传递给回调函数。
+
+
+
+
+```java
+ @ReactMethod
+ public void createCalendarEvent(String name, String location, Callback callBack) {
+ Integer eventId = ...
+ callBack.invoke(eventId);
+ }
+```
+
+
+
+
+```kotlin
+ @ReactMethod
+ fun createCalendarEvent(name: String, location: String, callback: Callback) {
+ val eventId = ...
+ callback.invoke(eventId)
+ }
+```
+
+
+
+
+然后就可以在 JavaScript 中使用以下方法:
+
+```tsx
+const onPress = () => {
+ CalendarModule.createCalendarEvent(
+ 'Party',
+ 'My House',
+ eventId => {
+ console.log(`Created a new event with id ${eventId}`);
+ },
+ );
+};
+```
+
+另一个需要注意的重要细节是,原生模块方法只能调用一次回调函数,这意味着你可以调用成功回调或失败回调,但不能两者兼得,而且每个回调最多只能被调用一次。不过,原生模块可以存储回调函数,并在以后调用它。
+
+处理回调错误有两种方法。第一种是遵循 Node 的惯例,将传给回调函数的第一个参数视为错误对象。
+
+
+
+
+```java
+ @ReactMethod
+ public void createCalendarEvent(String name, String location, Callback callBack) {
+ Integer eventId = ...
+ callBack.invoke(null, eventId);
+ }
+```
+
+
+
+
+```kotlin
+ @ReactMethod
+ fun createCalendarEvent(name: String, location: String, callback: Callback) {
+ val eventId = ...
+ callback.invoke(null, eventId)
+ }
+```
+
+
+
+
+在 JavaScript 中,你可以先检查第一个参数,看看是否传递了错误:
+
+```tsx
+const onPress = () => {
+ CalendarModule.createCalendarEvent(
+ 'testName',
+ 'testLocation',
+ (error, eventId) => {
+ if (error) {
+ console.error(`Error found! ${error}`);
+ }
+ console.log(`event id ${eventId} returned`);
+ },
+ );
+};
+```
+
+另一种选择是使用 onSuccess 和 onFailure 回调函数:
+
+
+
+
+```java
+@ReactMethod
+public void createCalendarEvent(String name, String location, Callback myFailureCallback, Callback mySuccessCallback) {
+}
+```
+
+
+
+
+```kotlin
+@ReactMethod
+ fun createCalendarEvent(
+ name: String,
+ location: String,
+ myFailureCallback: Callback,
+ mySuccessCallback: Callback
+ ) {}
+```
+
+
+
+
+在 JavaScript 中,您可以为错误和成功响应分别添加单独的回调函数:
+
+```tsx
+const onPress = () => {
+ CalendarModule.createCalendarEvent(
+ 'testName',
+ 'testLocation',
+ error => {
+ console.error(`Error found! ${error}`);
+ },
+ eventId => {
+ console.log(`event id ${eventId} returned`);
+ },
+ );
+};
+```
+
+### Promises
+
+原生模块也可以实现[Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise)承诺,这有助于简化您的 JavaScript 代码,尤其是在使用 ES2016 的[async/await](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function)语法时。当原生模块 Java/Kotlin 方法的最后一个参数为 Promise 时,对应的 JS 方法将返回一个 JS Promise 对象。
+
+用 Promise 重构上述代码,代码如下:
+
+
+
+
+```java
+import com.facebook.react.bridge.Promise;
+
+@ReactMethod
+public void createCalendarEvent(String name, String location, Promise promise) {
+ try {
+ Integer eventId = ...
+ promise.resolve(eventId);
+ } catch(Exception e) {
+ promise.reject("Create Event Error", e);
+ }
+}
+```
+
+
+
+
+```kotlin
+import com.facebook.react.bridge.Promise
+
+@ReactMethod
+fun createCalendarEvent(name: String, location: String, promise: Promise) {
+ try {
+ val eventId = ...
+ promise.resolve(eventId)
+ } catch (e: Throwable) {
+ promise.reject("Create Event Error", e)
+ }
+}
+```
+
+
+
+
+> 类似于回调,原生模块方法可以拒绝或解决一个 Promise(但不能两者都做),并且最多只能执行一次。这意味着您可以调用成功回调或失败回调, 但不能两者都调用,且每个回调最多只能被调用一次。不过,原生模块可以存储回调并稍后调用它。
+
+该方法的 JavaScript 对应部分返回一个 Promise。这意味着您可以在异步函数中使用 `await` 关键字调用它并等待其结果:
+
+```tsx
+const onSubmit = async () => {
+ try {
+ const eventId = await CalendarModule.createCalendarEvent(
+ 'Party',
+ 'My House',
+ );
+ console.log(`Created a new event with id ${eventId}`);
+ } catch (e) {
+ console.error(e);
+ }
+};
+```
+
+reject 方法接受以下几种参数组合:
+
+
+
+
+```java
+String code, String message, WritableMap userInfo, Throwable throwable
+```
+
+
+
+
+```kotlin
+code: String, message: String, userInfo: WritableMap, throwable: Throwable
+```
+
+
+
+
+更多详细内容,您可以在[这里](https://github.com/facebook/react-native/blob/main/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/Promise.java)查阅 `Promise.java` 接口。如果未提供 `userInfo`,React Native 会将其设置为 null。对于其余参数,React Native 将使用默认值。`message` 参数提供了显示在错误调用堆栈顶部的错误 `message`。以下是在 JavaScript 中显示的错误消息示例,该消息来自 Java/Kotlin 中的以下 reject 调用。
+
+Java/Kotlin 的 reject 调用:
+
+
+
+
+```java
+promise.reject("Create Event error", "Error parsing date", e);
+```
+
+
+
+
+```kotlin
+promise.reject("Create Event error", "Error parsing date", e)
+```
+
+
+
+
+在 React Native 应用中,如果 promise 被拒绝时,会抛出如下错误信息:
+
+
+
+### 向 JavaScript 发送事件
+
+原生模块无需直接调用即可向 JavaScript 发送事件信号。例如,您可能需要提醒 JavaScript 某项即将发生的原生 Android 日历应用程序日历事件。最简单的方式是使用从 ReactContext 中获取的 RCTDeviceEventEmitter,如下代码片段所示。
+
+
+
+
+```java
+...
+import com.facebook.react.modules.core.DeviceEventManagerModule;
+import com.facebook.react.bridge.WritableMap;
+import com.facebook.react.bridge.Arguments;
+...
+private void sendEvent(ReactContext reactContext,
+ String eventName,
+ @Nullable WritableMap params) {
+ reactContext
+ .getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
+ .emit(eventName, params);
+}
+
+private int listenerCount = 0;
+
+@ReactMethod
+public void addListener(String eventName) {
+ if (listenerCount == 0) {
+ // Set up any upstream listeners or background tasks as necessary
+ }
+
+ listenerCount += 1;
+}
+
+@ReactMethod
+public void removeListeners(Integer count) {
+ listenerCount -= count;
+ if (listenerCount == 0) {
+ // Remove upstream listeners, stop unnecessary background tasks
+ }
+}
+...
+WritableMap params = Arguments.createMap();
+params.putString("eventProperty", "someValue");
+...
+sendEvent(reactContext, "EventReminder", params);
+```
+
+
+
+
+```kotlin
+...
+import com.facebook.react.bridge.WritableMap
+import com.facebook.react.bridge.Arguments
+import com.facebook.react.modules.core.DeviceEventManagerModule
+...
+
+private fun sendEvent(reactContext: ReactContext, eventName: String, params: WritableMap?) {
+ reactContext
+ .getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
+ .emit(eventName, params)
+}
+
+private var listenerCount = 0
+
+@ReactMethod
+fun addListener(eventName: String) {
+ if (listenerCount == 0) {
+ // Set up any upstream listeners or background tasks as necessary
+ }
+
+ listenerCount += 1
+}
+
+@ReactMethod
+fun removeListeners(count: Int) {
+ listenerCount -= count
+ if (listenerCount == 0) {
+ // Remove upstream listeners, stop unnecessary background tasks
+ }
+}
+...
+val params = Arguments.createMap().apply {
+ putString("eventProperty", "someValue")
+}
+...
+sendEvent(reactContext, "EventReminder", params)
+```
+
+
+
+
+JavaScript 模块可通过在 [NativeEventEmitter](https://github.com/facebook/react-native/blob/main/packages/react-native/Libraries/EventEmitter/NativeEventEmitter.js) 类上调用 `addListener` 方法来注册接收事件。
+
+```tsx
+import {NativeEventEmitter, NativeModules} from 'react-native';
+...
+useEffect(() => {
+ const eventEmitter = new NativeEventEmitter(NativeModules.ToastExample);
+ let eventListener = eventEmitter.addListener('EventReminder', event => {
+ console.log(event.eventProperty) // "someValue"
+ });
+
+ // Removes the listener once unmounted
+ return () => {
+ eventListener.remove();
+ };
+ }, []);
+```
+
+### 从 startActivityForResult 获取结果
+
+如果你想从使用`startActivityForResult`启动的 Activity 中获取结果,需要监听`onActivityResult`。为此,你必须扩展`BaseActivityEventListener`或实现`ActivityEventListener`。前者更可取,因为它更有弹性应对 API 变化。然后,你需要在模块的构造函数中注册监听器,就像这样:
+
+
+
+
+```java
+reactContext.addActivityEventListener(mActivityResultListener);
+```
+
+
+
+
+```kotlin
+reactContext.addActivityEventListener(mActivityResultListener);
+```
+
+
+
+
+现在你可以通过实现以下方法来监听 `onActivityResult` 事件:
+
+
+
+
+```java
+@Override
+public void onActivityResult(
+ final Activity activity,
+ final int requestCode,
+ final int resultCode,
+ final Intent intent) {
+ // Your logic here
+}
+```
+
+
+
+
+```kotlin
+override fun onActivityResult(
+ activity: Activity?,
+ requestCode: Int,
+ resultCode: Int,
+ intent: Intent?
+) {
+ // Your logic here
+}
+```
+
+
+
+
+让我们实现一个基本的图像选择器来演示这一点。该图像选择器将向 JavaScript 暴露方法 `pickImage`,调用该方法时会返回图像路径。
+
+
+
+
+```kotlin
+public class ImagePickerModule extends ReactContextBaseJavaModule {
+
+ private static final int IMAGE_PICKER_REQUEST = 1;
+ private static final String E_ACTIVITY_DOES_NOT_EXIST = "E_ACTIVITY_DOES_NOT_EXIST";
+ private static final String E_PICKER_CANCELLED = "E_PICKER_CANCELLED";
+ private static final String E_FAILED_TO_SHOW_PICKER = "E_FAILED_TO_SHOW_PICKER";
+ private static final String E_NO_IMAGE_DATA_FOUND = "E_NO_IMAGE_DATA_FOUND";
+
+ private Promise mPickerPromise;
+
+ private final ActivityEventListener mActivityEventListener = new BaseActivityEventListener() {
+
+ @Override
+ public void onActivityResult(Activity activity, int requestCode, int resultCode, Intent intent) {
+ if (requestCode == IMAGE_PICKER_REQUEST) {
+ if (mPickerPromise != null) {
+ if (resultCode == Activity.RESULT_CANCELED) {
+ mPickerPromise.reject(E_PICKER_CANCELLED, "Image picker was cancelled");
+ } else if (resultCode == Activity.RESULT_OK) {
+ Uri uri = intent.getData();
+
+ if (uri == null) {
+ mPickerPromise.reject(E_NO_IMAGE_DATA_FOUND, "No image data found");
+ } else {
+ mPickerPromise.resolve(uri.toString());
+ }
+ }
+
+ mPickerPromise = null;
+ }
+ }
+ }
+ };
+
+ ImagePickerModule(ReactApplicationContext reactContext) {
+ super(reactContext);
+
+ // Add the listener for `onActivityResult`
+ reactContext.addActivityEventListener(mActivityEventListener);
+ }
+
+ @Override
+ public String getName() {
+ return "ImagePickerModule";
+ }
+
+ @ReactMethod
+ public void pickImage(final Promise promise) {
+ Activity currentActivity = getCurrentActivity();
+
+ if (currentActivity == null) {
+ promise.reject(E_ACTIVITY_DOES_NOT_EXIST, "Activity doesn't exist");
+ return;
+ }
+
+ // Store the promise to resolve/reject when picker returns data
+ mPickerPromise = promise;
+
+ try {
+ final Intent galleryIntent = new Intent(Intent.ACTION_PICK);
+
+ galleryIntent.setType("image/*");
+
+ final Intent chooserIntent = Intent.createChooser(galleryIntent, "Pick an image");
+
+ currentActivity.startActivityForResult(chooserIntent, IMAGE_PICKER_REQUEST);
+ } catch (Exception e) {
+ mPickerPromise.reject(E_FAILED_TO_SHOW_PICKER, e);
+ mPickerPromise = null;
+ }
+ }
+}
+```
+
+
+
+
+```kotlin
+class ImagePickerModule(reactContext: ReactApplicationContext) :
+ ReactContextBaseJavaModule(reactContext) {
+
+ private var pickerPromise: Promise? = null
+
+ private val activityEventListener =
+ object : BaseActivityEventListener() {
+ override fun onActivityResult(
+ activity: Activity?,
+ requestCode: Int,
+ resultCode: Int,
+ intent: Intent?
+ ) {
+ if (requestCode == IMAGE_PICKER_REQUEST) {
+ pickerPromise?.let { promise ->
+ when (resultCode) {
+ Activity.RESULT_CANCELED ->
+ promise.reject(E_PICKER_CANCELLED, "Image picker was cancelled")
+ Activity.RESULT_OK -> {
+ val uri = intent?.data
+
+ uri?.let { promise.resolve(uri.toString())}
+ ?: promise.reject(E_NO_IMAGE_DATA_FOUND, "No image data found")
+ }
+ }
+
+ pickerPromise = null
+ }
+ }
+ }
+ }
+
+ init {
+ reactContext.addActivityEventListener(activityEventListener)
+ }
+
+ override fun getName() = "ImagePickerModule"
+
+ @ReactMethod
+ fun pickImage(promise: Promise) {
+ val activity = currentActivity
+
+ if (activity == null) {
+ promise.reject(E_ACTIVITY_DOES_NOT_EXIST, "Activity doesn't exist")
+ return
+ }
+
+ pickerPromise = promise
+
+ try {
+ val galleryIntent = Intent(Intent.ACTION_PICK).apply { type = "image\/*" }
+
+ val chooserIntent = Intent.createChooser(galleryIntent, "Pick an image")
+
+ activity.startActivityForResult(chooserIntent, IMAGE_PICKER_REQUEST)
+ } catch (t: Throwable) {
+ pickerPromise?.reject(E_FAILED_TO_SHOW_PICKER, t)
+ pickerPromise = null
+ }
+ }
+
+ companion object {
+ const val IMAGE_PICKER_REQUEST = 1
+ const val E_ACTIVITY_DOES_NOT_EXIST = "E_ACTIVITY_DOES_NOT_EXIST"
+ const val E_PICKER_CANCELLED = "E_PICKER_CANCELLED"
+ const val E_FAILED_TO_SHOW_PICKER = "E_FAILED_TO_SHOW_PICKER"
+ const val E_NO_IMAGE_DATA_FOUND = "E_NO_IMAGE_DATA_FOUND"
+ }
+}
+```
+
+
+
+
+### 监听生命周期事件
+
+监听如 `onResume`、`onPause` 等活动的生命周期事件,跟实现 `ActivityEventListener` 的方式非常相似。该模块必须实现 `LifecycleEventListener`。然后,你需要在模块的构造函数中注册一个监听器,就像这样:
+
+
+
+
+```java
+reactContext.addLifecycleEventListener(this);
+```
+
+
+
+
+```kotlin
+reactContext.addLifecycleEventListener(this)
+```
+
+
+
+
+现在,通过实现以下方法,您可以监听活动的生命周期事件:
+
+
+
+
+```java
+@Override
+public void onHostResume() {
+ // Activity `onResume`
+}
+@Override
+public void onHostPause() {
+ // Activity `onPause`
+}
+@Override
+public void onHostDestroy() {
+ // Activity `onDestroy`
+}
+```
+
+
+
+
+```kotlin
+override fun onHostResume() {
+ // Activity `onResume`
+}
+
+override fun onHostPause() {
+ // Activity `onPause`
+}
+
+override fun onHostDestroy() {
+ // Activity `onDestroy`
+}
+```
+
+
+
+
+### 线程管理
+
+截至目前,在 Android 系统上,所有原生模块的异步方法都在同一个线程上执行。原生模块不应对它们被调用所在的线程作任何假设,因为当前的分配方式在未来可能会发生变化。如果需要进行阻塞调用,则应将繁重工作分派到内部管理的工作线程,并从那里分发任何回调。
diff --git a/cnwebsite/versioned_docs/version-0.75/native-modules-intro.md b/cnwebsite/versioned_docs/version-0.75/native-modules-intro.md
new file mode 100644
index 00000000000..c8bd1b44a5a
--- /dev/null
+++ b/cnwebsite/versioned_docs/version-0.75/native-modules-intro.md
@@ -0,0 +1,30 @@
+---
+id: native-modules-intro
+title: 原生模块简介
+---
+
+import NativeDeprecated from './the-new-architecture/\_markdown_native_deprecation.mdx'
+
+
+
+有时候 App 需要访问平台 API,但 React Native 可能还没有相应的模块包装;或者你需要复用一些 Java 代码,而不是用 Javascript 重新实现一遍;又或者你需要实现某些高性能的、多线程的代码,譬如图片处理、数据库、或者各种高级扩展等等。
+
+我们把 React Native 设计为可以在其基础上编写真正的原生代码,并且可以访问平台所有的能力。这是一个相对高级的特性,我们并不认为它应当在日常开发的过程中经常出现,但具备这样的能力是很重要的。如果 React Native 还不支持某个你需要的原生特性,你应当可以自己实现该特性的封装。
+
+## 创建原生模块
+
+有多种方法可以为您的 React Native 应用程序编写原生模块:
+
+1. 创建一个可在您的 React Native 应用程序中导入的原生库。阅读[创建原生库](local-library-setup)指南以了解更多信息。
+2. 直接在您的 React Native 应用程序的 iOS / Android 项目中
+3. 作为一个 NPM 包,可以被您/其他 React Native 应用程序作为依赖项安装。
+
+本指南将首先介绍如何直接在 React Native 应用程序内实现原生模块。但是,在以下指南中构建的原生模块可以作为 NPM 包进行分发。如果您有兴趣这样做,请查看[设置为 NPM 包的原生模块](native-modules-setup)指南。
+
+## 教程
+
+在接下来的部分中,我们将带您了解如何在 React Native 应用程序内直接构建一个原生模块的指南。作为一个先决条件,您需要一个 React Native 应用程序来工作。如果您还没有,可以按照[这里](getting-started)的步骤设置一个 React Native 应用程序。
+
+想象一下,您想在 React Native 应用程序内的 JavaScript 中访问 iOS/Android 原生日历 API,以创建日历事件。React Native 没有公开与原生日历库通信的 JavaScript API。然而,通过原生模块,您可以编写与原生日历 API 通信的原生代码。然后您可以在 React Native 应用程序中的 JavaScript 里调用该原生代码。
+
+在接下来的部分中,您将为[Android](native-modules-android)和[iOS](native-modules-ios)创建这样一个 Calendar 原生模块。
diff --git a/cnwebsite/versioned_docs/version-0.75/native-modules-ios.md b/cnwebsite/versioned_docs/version-0.75/native-modules-ios.md
new file mode 100644
index 00000000000..b544b2abb33
--- /dev/null
+++ b/cnwebsite/versioned_docs/version-0.75/native-modules-ios.md
@@ -0,0 +1,526 @@
+---
+id: native-modules-ios
+title: iOS 原生模块
+---
+
+import NativeDeprecated from './the-new-architecture/\_markdown_native_deprecation.mdx'
+
+
+
+有时候 App 需要访问平台 API,但 React Native 可能还没有相应的模块封装;或者你需要复用 Objective-C、Swift 或 C++代码,而不是用 JavaScript 重新实现一遍;又或者你需要实现某些高性能、多线程的代码,譬如图片处理、数据库、或者各种高级扩展等等。
+
+我们把 React Native 设计为可以在其基础上编写真正的原生代码,并且可以访问平台所有的能力。这是一个相对高级的特性,我们并不认为它应当在日常开发的过程中经常出现,但具备这样的能力是很重要的。如果 React Native 还不支持某个你需要的原生特性,你应当可以自己实现该特性的封装。
+
+本文是关于如何封装原生模块的高级向导,我们假设您已经具备 Objective-C 或者 Swift,以及 iOS 核心库(Foundation、UIKit)的相关知识。
+
+## 原生模块设置
+
+原生模块通常作为 npm 包进行分发,只是要成为原生模块,它们将包含一个 Xcode 库项目。要获得基本的框架,请务必先阅读[原生模块设置](native-modules-setup)指南。
+
+## iOS 日历模块演示
+
+本向导将会用[iOS 日历 API](https://developer.apple.com/library/mac/documentation/DataManagement/Conceptual/EventKitProgGuide/Introduction/Introduction.html)作为示例。我们的目标就是在 Javascript 中可以访问到 iOS 的日历功能。
+
+在 React Native 中,一个“原生模块”就是一个实现了“RCTBridgeModule”协议的 Objective-C 类,其中 RCT 是 ReaCT 的缩写。
+
+```objectivec
+// CalendarManager.h
+#import
+
+@interface CalendarManager : NSObject
+@end
+```
+
+为了实现`RCTBridgeModule`协议,你的类需要包含`RCT_EXPORT_MODULE()`宏。这个宏也可以添加一个参数用来指定在 JavaScript 中访问这个模块的名字。如果你不指定,默认就会使用这个 Objective-C 类的名字。如果类名以 RCT 开头,则 JavaScript 端引入的模块名会自动移除这个前缀。
+
+```objectivec
+// CalendarManager.m
+#import "CalendarManager.h"
+
+@implementation CalendarManager
+
+// To export a module named CalendarManager
+RCT_EXPORT_MODULE();
+
+// This would name the module AwesomeCalendarManager instead
+// RCT_EXPORT_MODULE(AwesomeCalendarManager);
+
+@end
+```
+
+你必须明确的声明要给 JavaScript 导出的方法,否则 React Native 不会导出任何方法。声明通过`RCT_EXPORT_METHOD()`宏来实现:
+
+```objectivec
+#import "CalendarManager.h"
+#import
+
+@implementation CalendarManager
+
+RCT_EXPORT_MODULE();
+
+RCT_EXPORT_METHOD(addEvent:(NSString *)name location:(NSString *)location)
+{
+ RCTLogInfo(@"Pretending to create an event %@ at %@", name, location);
+}
+
+@end
+```
+
+现在从 Javascript 里可以这样调用这个方法:
+
+```jsx
+import {NativeModules} from 'react-native';
+const CalendarManager = NativeModules.CalendarManager;
+CalendarManager.addEvent(
+ 'Birthday Party',
+ '4 Privet Drive, Surrey',
+);
+```
+
+> **注意**: JavaScript 方法名
+>
+> 导出到 JavaScript 的方法名是 Objective-C 的方法名的第一个部分。React Native 还定义了一个`RCT_REMAP_METHOD()`宏,它可以指定 JavaScript 方法名。因为 JavaScript 端不能有同名不同参的方法存在,所以当原生端存在重载方法时,可以使用这个宏来避免在 JavaScript 端的名字冲突。
+
+The CalendarManager module is instantiated on the Objective-C side using a [CalendarManager new] call. 桥接到 JavaScript 的方法返回值类型必须是`void`。React Native 的桥接操作是异步的,所以要返回结果给 JavaScript,你必须通过回调或者触发事件来进行。(参见本文档后面的部分)
+
+## 参数类型
+
+`RCT_EXPORT_METHOD` 支持所有标准 JSON 类型,包括:
+
+- string (`NSString`)
+- number (`NSInteger`, `float`, `double`, `CGFloat`, `NSNumber`)
+- boolean (`BOOL`, `NSNumber`)
+- array (`NSArray`) 可包含本列表中任意类型
+- object (`NSDictionary`) 可包含 string 类型的键和本列表中任意类型的值
+- function (`RCTResponseSenderBlock`)
+
+除此以外,任何`RCTConvert`类支持的的类型也都可以使用(参见[`RCTConvert`](https://github.com/facebook/react-native/blob/master/React/Base/RCTConvert.h)了解更多信息)。`RCTConvert`还提供了一系列辅助函数,用来接收一个 JSON 值并转换到原生 Objective-C 类型或类。
+
+在我们的`CalendarManager`例子里,我们需要把事件的时间交给原生方法。我们不能在桥接通道里传递 Date 对象,所以需要把日期转化成字符串或数字来传递。我们可以这么实现原生函数:
+
+```objectivec
+RCT_EXPORT_METHOD(addEvent:(NSString *)name location:(NSString *)location date:(nonnull NSNumber *)secondsSinceUnixEpoch)
+{
+ NSDate *date = [RCTConvert NSDate:secondsSinceUnixEpoch];
+}
+```
+
+或者这样:
+
+```objectivec
+RCT_EXPORT_METHOD(addEvent:(NSString *)name location:(NSString *)location date:(NSString *)ISO8601DateString)
+{
+ NSDate *date = [RCTConvert NSDate:ISO8601DateString];
+}
+```
+
+不过我们可以依靠自动类型转换的特性,跳过手动的类型转换,而直接这么写:
+
+```objectivec
+RCT_EXPORT_METHOD(addEvent:(NSString *)name location:(NSString *)location date:(NSDate *)date)
+{
+ // Date is ready to use!
+}
+```
+
+对应 JavaScript 端既可以这样:
+
+```jsx
+CalendarManager.addEvent(
+ 'Birthday Party',
+ '4 Privet Drive, Surrey',
+ date.getTime(),
+); // 把日期以unix时间戳形式传递
+```
+
+也可以这样:
+
+```jsx
+CalendarManager.addEvent(
+ 'Birthday Party',
+ '4 Privet Drive, Surrey',
+ date.toISOString(),
+); // 把日期以ISO-8601的字符串形式传递
+```
+
+两个值都会被转换为正确的`NSDate`类型。但如果提供一个不合法的值,譬如一个`Array`,则会产生一个“红屏”报错信息。
+
+随着`CalendarManager.addEvent`方法变得越来越复杂,参数的个数越来越多,其中有一些可能是可选的参数。在这种情况下我们应该考虑修改我们的 API,用一个 dictionary 来存放所有的事件参数,像这样:
+
+```objectivec
+#import
+
+RCT_EXPORT_METHOD(addEvent:(NSString *)name details:(NSDictionary *)details)
+{
+ NSString *location = [RCTConvert NSString:details[@"location"]];
+ NSDate *time = [RCTConvert NSDate:details[@"time"]];
+ ...
+}
+```
+
+然后在 JS 里这样调用:
+
+```jsx
+CalendarManager.addEvent('Birthday Party', {
+ location: '4 Privet Drive, Surrey',
+ time: date.getTime(),
+ description: '...',
+});
+```
+
+> **注意**: 关于数组和映射
+>
+> Objective-C 并没有提供确保这些结构体内部值的类型的方式。你的原生模块可能希望收到一个字符串数组,但如果 JavaScript 在调用的时候提供了一个混合 number 和 string 的数组,你会收到一个`NSArray`,里面既有`NSNumber`也有`NSString`。对于数组来说,`RCTConvert`提供了一些类型化的集合,譬如`NSStringArray`或者`UIColorArray`,你可以用在你的函数声明中。对于映射而言,开发者有责任自己调用`RCTConvert`的辅助方法来检测和转换值的类型。
+
+## 回调函数
+
+> **警告**
+>
+> 本章节内容目前还处在实验阶段,因为我们还并没有太多的实践经验来处理回调函数。
+
+原生模块还支持一种特殊的参数——回调函数。它提供了一个函数来把返回值传回给 JavaScript。
+
+```objectivec
+RCT_EXPORT_METHOD(findEvents:(RCTResponseSenderBlock)callback)
+{
+ NSArray *events = ...
+ callback(@[[NSNull null], events]);
+}
+```
+
+`RCTResponseSenderBlock`只接受一个参数——传递给 JavaScript 回调函数的参数数组。在上面这个例子里我们用 Node.js 的常用习惯:第一个参数是一个错误对象(没有发生错误的时候为 null),而剩下的部分是函数的返回值。
+
+```jsx
+CalendarManager.findEvents((error, events) => {
+ if (error) {
+ console.error(error);
+ } else {
+ this.setState({events: events});
+ }
+});
+```
+
+原生模块通常只应调用回调函数一次。但是,它可以保存 callback 并在将来调用。这在封装那些通过“委托函数”来获得返回值的 iOS API 时最为常见。[`RCTAlertManager`](https://github.com/facebook/react-native/blob/master/React/Modules/RCTAlertManager.m)中就属于这种情况。
+
+如果你想传递一个更接近`Error`类型的对象给 JavaScript,可以用[`RCTUtils.h`](https://github.com/facebook/react-native/blob/master/React/Base/RCTUtils.h)提供的`RCTMakeError`函数。现在它仅仅是发送了一个和 Error 结构一样的 dictionary 给 JavaScript,但我们考虑在将来版本里让它产生一个真正的`Error`对象。
+
+## Promises
+
+**译注**:这一部分涉及到较新的 js 语法和特性,不熟悉的读者建议先阅读 ES6 的相关书籍和文档。
+
+原生模块还可以使用 promise 来简化代码,搭配 ES2016(ES7)标准的`async/await`语法则效果更佳。如果桥接原生方法的最后两个参数是`RCTPromiseResolveBlock`和`RCTPromiseRejectBlock`,则对应的 JS 方法就会返回一个 Promise 对象。
+
+我们把上面的代码用 promise 来代替回调进行重构:
+
+```objectivec
+RCT_REMAP_METHOD(findEvents,
+ findEventsWithResolver:(RCTPromiseResolveBlock)resolve
+ rejecter:(RCTPromiseRejectBlock)reject)
+{
+ NSArray *events = ...
+ if (events) {
+ resolve(events);
+ } else {
+ NSError *error = ...
+ reject(@"no_events", @"There were no events", error);
+ }
+}
+```
+
+现在 JavaScript 端的方法会返回一个 Promise。这样你就可以在一个声明了`async`的异步函数内使用`await`关键字来调用,并等待其结果返回。(虽然这样写着看起来像同步操作,但实际仍然是异步的,并不会阻塞执行来等待)。
+
+```jsx
+async function updateEvents() {
+ try {
+ const events = await CalendarManager.findEvents();
+
+ this.setState({events});
+ } catch (e) {
+ console.error(e);
+ }
+}
+
+updateEvents();
+```
+
+## 多线程
+
+原生模块不应对自己被调用时所处的线程做任何假设。React Native 在一个独立的串行 GCD 队列中调用原生模块的方法,但这属于实现的细节,并且可能会在将来的版本中改变。通过实现方法`- (dispatch_queue_t)methodQueue`,原生模块可以指定自己想在哪个队列中被执行。具体来说,如果模块需要调用一些必须在主线程才能使用的 API,那应当这样指定:
+
+```objectivec
+- (dispatch_queue_t)methodQueue
+{
+ return dispatch_get_main_queue();
+}
+```
+
+类似的,如果一个操作需要花费很长时间,原生模块不应该阻塞住,而是应当声明一个用于执行操作的独立队列。举个例子,`RCTAsyncLocalStorage`模块创建了自己的一个 queue,这样它在做一些较慢的磁盘操作的时候就不会阻塞住 React 本身的消息队列:
+
+```objectivec
+- (dispatch_queue_t)methodQueue
+{
+ return dispatch_queue_create("com.facebook.React.AsyncLocalStorageQueue", DISPATCH_QUEUE_SERIAL);
+}
+```
+
+指定的`methodQueue`会被你模块里的所有方法共享。如果你的方法中“只有一个”是耗时较长的(或者是由于某种原因必须在不同的队列中运行的),你可以在函数体内用`dispatch_async`方法来在另一个队列执行,而不影响其他方法:
+
+```objectivec
+RCT_EXPORT_METHOD(doSomethingExpensive:(NSString *)param callback:(RCTResponseSenderBlock)callback)
+{
+ dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
+ // 在这里执行长时间的操作
+ ...
+ // 你可以在任何线程/队列中执行回调函数
+ callback(@[...]);
+ });
+}
+```
+
+> **注意**: 在模块之间共享分发队列
+>
+> `methodQueue`方法会在模块被初始化的时候被执行一次,然后会被 React Native 的桥接机制保存下来,所以你不需要自己保存队列的引用,除非你希望在模块的其它地方使用它。但是,如果你希望在若干个模块中共享同一个队列,则需要自己保存并返回相同的队列实例;仅仅是返回相同名字的队列是不行的。
+
+## 依赖注入
+
+bridge 会自动注册实现了`RCTBridgeModule`协议的模块,但是你可能也希望能够自己去初始化自定义的模块实例(这样可以注入依赖)。
+
+要实现这个功能,你需要实现`RCTBridgeDelegate`协议,初始化`RCTBridge`,并且在初始化方法里指定代理。然后用初始化好的`RCTBridge`实例初始化一个`RCTRootView`。
+
+```objectivec
+id moduleInitialiser = [[classThatImplementsRCTBridgeDelegate alloc] init];
+
+RCTBridge *bridge = [[RCTBridge alloc] initWithDelegate:moduleInitialiser launchOptions:nil];
+
+RCTRootView *rootView = [[RCTRootView alloc]
+ initWithBridge:bridge
+ moduleName:kModuleName
+ initialProperties:nil];
+```
+
+## 导出常量
+
+原生模块可以导出一些常量,这些常量在 JavaScript 端随时都可以访问。用这种方法来传递一些静态数据,可以避免通过 bridge 进行一次来回交互。
+
+```objectivec
+- (NSDictionary *)constantsToExport
+{
+ return @{ @"firstDayOfTheWeek": @"Monday" };
+}
+```
+
+JavaScript 端可以随时同步地访问这个数据:
+
+```jsx
+console.log(CalendarManager.firstDayOfTheWeek);
+```
+
+但是注意这个常量仅仅在初始化的时候导出了一次,所以即使你在运行期间改变`constantToExport`返回的值,也不会影响到 JavaScript 环境下所得到的结果。
+
+### 实现 `+ requiresMainQueueSetup`
+
+如果您重写 `- constantsToExport`,那么您也应该实现 `+ requiresMainQueueSetup`,以便让 React Native 知道您的模块是否需要在主线程上初始化。否则,您将会看到一个警告:在未来,除非您明确选择退出使用 `+ requiresMainQueueSetup`,否则您的模块可能会在后台线程上进行初始化。
+
+```objectivec
++ (BOOL)requiresMainQueueSetup
+{
+ return YES; // 请仅在您的模块初始化需要调用 UIKit 时才这样做!
+}
+```
+
+````Swift
+// Swift
+// CalendarManager.swift
+@objc(CalendarManager)
+class CalendarManager: NSObject, RCTBridgeModule {
+static func moduleName() -> String! {
+ return "CalendarManager";
+}
+static func requiresMainQueueSetup() -> Bool {
+ return true
+}
+```
+
+如果你的模块不需要访问 UIKit, 那么应该在实现 `+requiresMainQueueSetup` 方法时返回 `NO` 。
+
+### 枚举常量
+
+用`NS_ENUM`定义的枚举类型必须要先扩展对应的 RCTConvert 方法才可以作为函数参数传递。
+
+假设我们要导出如下的`NS_ENUM`定义:
+
+```objectivec
+typedef NS_ENUM(NSInteger, UIStatusBarAnimation) {
+ UIStatusBarAnimationNone,
+ UIStatusBarAnimationFade,
+ UIStatusBarAnimationSlide,
+};
+````
+
+你需要这样来扩展 RCTConvert 类:
+
+```objectivec
+@implementation RCTConvert (StatusBarAnimation)
+ RCT_ENUM_CONVERTER(UIStatusBarAnimation, (@{ @"statusBarAnimationNone" : @(UIStatusBarAnimationNone),
+ @"statusBarAnimationFade" : @(UIStatusBarAnimationFade),
+ @"statusBarAnimationSlide" : @(UIStatusBarAnimationSlide)}),
+ UIStatusBarAnimationNone, integerValue)
+@end
+```
+
+接着你可以这样定义方法并且导出 enum 值作为常量:
+
+```objectivec
+- (NSDictionary *)constantsToExport
+{
+ return @{ @"statusBarAnimationNone" : @(UIStatusBarAnimationNone),
+ @"statusBarAnimationFade" : @(UIStatusBarAnimationFade),
+ @"statusBarAnimationSlide" : @(UIStatusBarAnimationSlide) };
+};
+
+RCT_EXPORT_METHOD(updateStatusBarAnimation:(UIStatusBarAnimation)animation
+ completion:(RCTResponseSenderBlock)callback)
+```
+
+你的枚举现在会用上面提供的选择器进行转换(上面的例子中是`integerValue`),然后再传递给你导出的函数。
+
+## 给 JavaScript 端发送事件
+
+即使没有被 JavaScript 调用,原生模块也可以给 JavaScript 发送事件通知。最好的方法是继承`RCTEventEmitter`,实现`suppportEvents`方法并调用`self sendEventWithName:`。
+
+```objectivec
+// CalendarManager.h
+#import
+#import
+
+@interface CalendarManager : RCTEventEmitter
+
+@end
+```
+
+```objectivec
+// CalendarManager.m
+#import "CalendarManager.h"
+
+@implementation CalendarManager
+
+RCT_EXPORT_MODULE();
+
+- (NSArray *)supportedEvents
+{
+ return @[@"EventReminder"];
+}
+
+- (void)calendarEventReminderReceived:(NSNotification *)notification
+{
+ NSString *eventName = notification.userInfo[@"name"];
+ [self sendEventWithName:@"EventReminder" body:@{@"name": eventName}];
+}
+
+@end
+```
+
+JavaScript 端的代码可以创建一个包含你的模块的`NativeEventEmitter`实例来订阅这些事件。
+
+```jsx
+import { NativeEventEmitter, NativeModules } from 'react-native';
+const { CalendarManager } = NativeModules;
+
+const calendarManagerEmitter = new NativeEventEmitter(CalendarManager);
+
+const subscription = calendarManagerEmitter.addListener(
+ 'EventReminder',
+ (reminder) => console.log(reminder.name)
+);
+...
+// 别忘了取消订阅,通常在componentWillUnmount生命周期方法中实现。
+subscription.remove();
+```
+
+### 优化无监听处理的事件
+
+如果你发送了一个事件却没有任何监听处理,则会因此收到一个资源警告。要优化因此带来的额外开销,你可以在你的`RCTEventEmitter`子类中覆盖`startObserving`和`stopObserving`方法。
+
+```objectivec
+@implementation CalendarManager
+{
+ bool hasListeners;
+}
+
+// 在添加第一个监听函数时触发
+-(void)startObserving {
+ hasListeners = YES;
+ // Set up any upstream listeners or background tasks as necessary
+}
+
+// Will be called when this module's last listener is removed, or on dealloc.
+-(void)stopObserving {
+ hasListeners = NO;
+ // Remove upstream listeners, stop unnecessary background tasks
+}
+
+- (void)calendarEventReminderReceived:(NSNotification *)notification
+{
+ NSString *eventName = notification.userInfo[@"name"];
+ if (hasListeners) { // Only send events if anyone is listening
+ [self sendEventWithName:@"EventReminder" body:@{@"name": eventName}];
+ }
+}
+```
+
+## 从 Swift 导出
+
+Swift 不支持宏,所以从 Swift 向 React Native 导出类和函数需要多做一些设置,但是大致与 Objective-C 是相同的。
+
+假设我们已经有了一个一样的`CalendarManager`,不过是用 Swift 实现的类:
+
+```swift
+// CalendarManager.swift
+
+@objc(CalendarManager)
+class CalendarManager: NSObject {
+
+ @objc(addEvent:location:date:)
+ func addEvent(name: String, location: String, date: NSNumber) -> Void {
+ // Date is ready to use!
+ }
+
+ @objc
+ func constantsToExport() -> [String: Any]! {
+ return ["someKey": "someValue"]
+ }
+
+}
+```
+
+> **注意**: 你必须使用@objc 标记来确保类和函数对 Objective-C 公开。
+
+接着,创建一个私有的实现文件,并将必要的信息注册到 React Native 中。
+
+```objectivec
+// CalendarManagerBridge.m
+#import
+
+@interface RCT_EXTERN_MODULE(CalendarManager, NSObject)
+
+RCT_EXTERN_METHOD(addEvent:(NSString *)name location:(NSString *)location date:(nonnull NSNumber *)date)
+
+@end
+```
+
+请注意,一旦你[在 IOS 中混用 2 种语言](https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/BuildingCocoaApps/MixandMatch.html), 那就还需要一个额外的桥接头文件,称作“bridging header”,用来导出 Objective-C 文件给 Swift。如果你是通过 Xcode 菜单中的`File>New File`来创建的 Swift 文件,Xcode 会自动为你创建这个头文件。在这个头文件中,你需要引入`RCTBridgeModule.h`。
+
+```objectivec
+// CalendarManager-Bridging-Header.h
+#import
+```
+
+同样的,你也可以使用`RCT_EXTERN_REMAP_MODULE`和`RCT_EXTERN_REMAP_METHOD`来改变导出模块和方法的 JavaScript 调用名称。了解更多信息,请参阅[`RCTBridgeModule`](https://github.com/facebook/react-native/blob/master/React/Base/RCTBridgeModule.h).
+
+> **在制作第三方模块时的重要注意事项**: 只有 Xcode 9 及更高版本才支持在静态库中使用 Swift。为了在使用包含在模块中的 iOS 静态库中的 Swift 时构建 Xcode 项目,您的主应用程序项目必须包含 Swift 代码和桥接头文件本身。如果您的应用程序项目不包含任何 Swift 代码,则解决方法可以是一个空的 .swift 文件和一个空的桥接头。
+
+# 保留的方法名
+
+## invalidate()
+
+在 iOS 上,原生模块可以通过实现 `invalidate` 方法来符合 [RCTInvalidating](https://github.com/facebook/react-native/blob/aa0ef15335fe27c0c193e3e968789886d82e82ed/React/Base/RCTInvalidating.h) 协议。当本地桥接被失效时(例如:开发模式重新加载),可以调用这个方法[链接](https://github.com/facebook/react-native/blob/18e3303cd46a72668caae46e28c7c6ae69fbf8f8/ReactCommon/turbomodule/core/platform/ios/RCTTurboModuleManager.mm#L456)。通常情况下,您应避免实现此方法,因为这种机制是为了向后兼容而存在的,未来可能会被移除。
diff --git a/cnwebsite/versioned_docs/version-0.75/navigation.md b/cnwebsite/versioned_docs/version-0.75/navigation.md
new file mode 100644
index 00000000000..0148173f2b5
--- /dev/null
+++ b/cnwebsite/versioned_docs/version-0.75/navigation.md
@@ -0,0 +1,16 @@
+---
+id: navigation
+title: 使用导航器跳转页面
+---
+
+移动应用基本不会只由一个页面组成。管理多个页面的呈现、跳转的组件就是我们通常所说的导航器(navigator)。
+
+本文档总结对比了 React Native 中现有的几个导航组件。如果你刚开始接触,那么直接选择[React Navigation](navigation.md#react-navigation)就好。 React Navigation 提供了简单易用的跨平台导航方案,在 iOS 和 Android 上都可以进行翻页式、tab 选项卡式和抽屉式的导航布局。
+
+如果你想同时在 iOS 和 Android 上达到看起来像原生,或者你想把 RN 整合到一个已经有原生导航管理的 APP 里, 下面这个库提供了在两个平台都适用的原生导航: [react-native-navigation](https://github.com/wix/react-native-navigation).
+
+## React Navigation
+
+社区今后主推的方案是一个单独的导航库`react-navigation`,它的使用十分简单。React Navigation 中的视图是原生组件,同时用到了运行在原生线程上的`Animated`动画库,因而性能表现十分流畅。此外其动画形式和手势都非常便于定制。
+
+要想详细了解 React Navigation 的具体用法,请访问其[官方网站](https://reactnavigation.org/)。
diff --git a/cnwebsite/versioned_docs/version-0.75/netinfo.md b/cnwebsite/versioned_docs/version-0.75/netinfo.md
new file mode 100644
index 00000000000..92d81573ddd
--- /dev/null
+++ b/cnwebsite/versioned_docs/version-0.75/netinfo.md
@@ -0,0 +1,166 @@
+---
+id: netinfo
+title: NetInfo
+---
+
+> **已过时。** Use [react-native-community/react-native-netinfo](https://github.com/react-native-community/react-native-netinfo) instead.
+
+通过 NetInfo 模块可以获取设备当前的联网状态。
+
+```
+NetInfo.getConnectionInfo().then((connectionInfo) => {
+ console.log('Initial, type: ' + connectionInfo.type + ', effectiveType: ' + connectionInfo.effectiveType);
+});
+function handleFirstConnectivityChange(connectionInfo) {
+ console.log('First change, type: ' + connectionInfo.type + ', effectiveType: ' + connectionInfo.effectiveType);
+ NetInfo.removeEventListener(
+ 'connectionChange',
+ handleFirstConnectivityChange
+ );
+}
+NetInfo.addEventListener(
+ 'connectionChange',
+ handleFirstConnectivityChange
+);
+```
+
+### ConnectionType 枚举值
+
+`ConnectionType`描述了设备联网的方式。
+
+`ConnectionType`有如下跨平台可用的值:
+
+- `none` - 设备处于离线状态
+- `wifi` - 设备通过 wifi 联网,或者设备是 iOS 模拟器
+- `cellular` - 设备通过蜂窝数据流量联网
+- `unknown` - 联网状态异常
+
+`ConnectionType`还有如下仅在 Android 平台上可用的值:
+
+- `bluetooth` - 设备通过蓝牙协议联网
+- `ethernet` - 设备通过以太网协议联网
+- `wimax` - 设备通过 WiMAX 协议联网
+
+### EffectiveConnectionType 枚举值
+
+`EffectiveConnectionType`有如下跨平台可用的值:
+
+- `2g`
+- `3g`
+- `4g`
+- `unknown`
+
+### Android
+
+要在 Android 上获取联网状态,还需要在`AndroidManifest.xml`中添加如下权限请求:
+
+``
+
+### 查看方法
+
+- [`addEventListener`](netinfo.md#addeventlistener)
+- [`removeEventListener`](netinfo.md#removeeventlistener)
+- [`getConnectionInfo`](netinfo.md#getconnectioninfo)
+- [`isConnectionExpensive`](netinfo.md#isconnectionexpensive)
+
+### 查看属性
+
+- [`isConnected`](netinfo.md#isconnected)
+
+---
+
+# 文档
+
+## 方法
+
+### `addEventListener()`
+
+```jsx
+NetInfo.addEventListener(eventName, handler);
+```
+
+添加一个事件监听函数。
+
+**参数:**
+
+| 名称 | 类型 | 必需 | 说明 |
+| --------- | ------------------------------ | ---- | -------- |
+| eventName | enum(connectionChange, change) | 是 | 事件名 |
+| handler | function | 是 | 监听函数 |
+
+支持的事件名:
+
+- `connectionChange`:当联网状态改变时触发。传给监听函数的参数是一个对象,包含有下列属性:
+ - `type`: 上面所列出的`ConnectionType`值
+ - `effectiveType`: 上面所列出的`EffectiveConnectionType`值
+- `change`: 这一事件已过时。请使用`connectionChange`代替。当联网状态改变时触发。
+
+---
+
+### `removeEventListener()`
+
+```jsx
+NetInfo.removeEventListener(eventName, handler);
+```
+
+移除联网状态改变的监听函数。
+
+**参数:**
+
+| 名称 | 类型 | 必需 | 说明 |
+| --------- | ------------------------------ | ---- | -------- |
+| eventName | enum(connectionChange, change) | 是 | 事件名 |
+| handler | function | 是 | 监听函数 |
+
+---
+
+### `getConnectionInfo()`
+
+```jsx
+NetInfo.getConnectionInfo();
+```
+
+返回一个 promise,最终解析值为带有`type`和`effectiveType`属性的对象。其中`type`属性的值为[`ConnectionType`](netinfo.md#connectiontype-enum) ,而`effectiveType`属性的值为[`EffectiveConnectionType`](netinfo.md#effectiveconnectiontype-enum))。
+
+---
+
+### `isConnectionExpensive()`
+
+```jsx
+NetInfo.isConnectionExpensive();
+```
+
+仅 Android 可用。用于判断当前活动的连接是否计费。如果当前连接是通过移动数据网络,或者通过基于移动数据网络所创建的 wifi 热点,或是大量消耗电池等等,都有可能被判定为计费的数据连接。
+
+```
+NetInfo.isConnectionExpensive()
+.then(isConnectionExpensive => {
+ console.log('Connection is ' + (isConnectionExpensive ? 'Expensive' : 'Not Expensive'));
+})
+.catch(error => {
+ console.error(error);
+});
+```
+
+## 属性
+
+### `isConnected`
+
+在所有平台上可用。以异步方式获取一个布尔值,用于判断当前设备是否联网。
+
+```
+NetInfo.isConnected.fetch().then(isConnected => {
+ console.log('First, is ' + (isConnected ? 'online' : 'offline'));
+});
+function handleFirstConnectivityChange(isConnected) {
+ console.log('Then, is ' + (isConnected ? 'online' : 'offline'));
+ NetInfo.isConnected.removeEventListener(
+ 'connectionChange',
+ handleFirstConnectivityChange
+ );
+}
+NetInfo.isConnected.addEventListener(
+ 'connectionChange',
+ handleFirstConnectivityChange
+);
+```
diff --git a/cnwebsite/versioned_docs/version-0.75/network.md b/cnwebsite/versioned_docs/version-0.75/network.md
new file mode 100644
index 00000000000..06f8a76d40f
--- /dev/null
+++ b/cnwebsite/versioned_docs/version-0.75/network.md
@@ -0,0 +1,274 @@
+---
+id: network
+title: 访问网络
+---
+
+import Tabs from '@theme/Tabs'; import TabItem from '@theme/TabItem'; import constants from '@site/core/TabsConstants';
+
+很多移动应用都需要从远程地址中获取数据或资源。你可能需要给某个 REST API 发起 POST 请求以提交用户数据,又或者可能仅仅需要从某个服务器上获取一些静态内容——以下就是你会用到的东西。新手可以对照这个[简短的视频教程](http://v.youku.com/v_show/id_XMTUyNTEwMTA5Ng==.html)加深理解。
+
+## 使用 Fetch
+
+React Native 提供了和 web 标准一致的[Fetch API](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API),用于满足开发者访问网络的需求。如果你之前使用过`XMLHttpRequest`(即俗称的 ajax)或是其他的网络 API,那么 Fetch 用起来将会相当容易上手。这篇文档只会列出 Fetch 的基本用法,并不会讲述太多细节,你可以使用你喜欢的搜索引擎去搜索`fetch api`关键字以了解更多信息。
+
+### 发起请求
+
+要从任意地址获取内容的话,只需简单地将网址作为参数传递给 fetch 方法即可(fetch 这个词本身也就是`获取`的意思):
+
+```jsx
+fetch('https://mywebsite.com/mydata.json');
+```
+
+Fetch 还有可选的第二个参数,可以用来定制 HTTP 请求一些参数。你可以指定 header 参数,或是指定使用 POST 方法,又或是提交数据等等:
+
+```jsx
+fetch('https://mywebsite.com/endpoint/', {
+ method: 'POST',
+ headers: {
+ Accept: 'application/json',
+ 'Content-Type': 'application/json',
+ },
+ body: JSON.stringify({
+ firstParam: 'yourValue',
+ secondParam: 'yourOtherValue',
+ }),
+});
+```
+
+提交数据的格式关键取决于 headers 中的`Content-Type`。`Content-Type`有很多种,对应 body 的格式也有区别。到底应该采用什么样的`Content-Type`取决于服务器端,所以请和服务器端的开发人员沟通确定清楚。常用的'Content-Type'除了上面的'application/json',还有传统的网页表单形式,示例如下:
+
+```js
+fetch('https://mywebsite.com/endpoint/', {
+ method: 'POST',
+ headers: {
+ 'Content-Type': 'application/x-www-form-urlencoded',
+ },
+ body: 'key1=value1&key2=value2',
+});
+```
+
+可以参考[Fetch 请求文档](https://developer.mozilla.org/en-US/docs/Web/API/Request)来查看所有可用的参数。
+
+> 注意:使用 Chrome 调试目前无法观测到 React Native 中的网络请求,你可以使用第三方的[react-native-debugger](https://github.com/jhen0409/react-native-debugger)来进行观测。
+
+### 处理服务器的响应数据
+
+上面的例子演示了如何发起请求。很多情况下,你还需要处理服务器回复的数据。
+
+网络请求天然是一种异步操作。Fetch 方法会返回一个[Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise),这种模式可以简化异步风格的代码(译注:同样的,如果你不了解 promise,建议使用搜索引擎补课):
+
+```jsx
+function getMoviesFromApiAsync() {
+ return fetch(
+ 'https://facebook.github.io/react-native/movies.json',
+ )
+ .then(response => response.json())
+ .then(responseJson => {
+ return responseJson.movies;
+ })
+ .catch(error => {
+ console.error(error);
+ });
+}
+```
+
+你也可以在 React Native 应用中使用 ES2017 标准中的`async`/`await` 语法:
+
+```jsx
+// 注意这个方法前面有async关键字
+async function getMoviesFromApi() {
+ try {
+ // 注意这里的await语句,其所在的函数必须有async关键字声明
+ let response = await fetch(
+ 'https://facebook.github.io/react-native/movies.json',
+ );
+ let responseJson = await response.json();
+ return responseJson.movies;
+ } catch (error) {
+ console.error(error);
+ }
+}
+```
+
+别忘了 catch 住`fetch`可能抛出的异常,否则出错时你可能看不到任何提示。
+
+
+
+
+```SnackPlayer name=Fetch%20Example
+import React, { useEffect, useState } from 'react';
+import { ActivityIndicator, FlatList, Text, View } from 'react-native';
+
+export default App = () => {
+ const [isLoading, setLoading] = useState(true);
+ const [data, setData] = useState([]);
+
+ useEffect(() => {
+ fetch('https://reactnative.dev/movies.json')
+ .then((response) => response.json())
+ .then((json) => setData(json.movies))
+ .catch((error) => console.error(error))
+ .finally(() => setLoading(false));
+ }, []);
+
+ return (
+
+ {isLoading ? : (
+ id}
+ renderItem={({ item }) => (
+ {item.title}, {item.releaseYear}
+ )}
+ />
+ )}
+
+ );
+};
+```
+
+
+
+
+```SnackPlayer name=Fetch%20Example
+import React, { Component } from 'react';
+import { ActivityIndicator, FlatList, Text, View } from 'react-native';
+
+export default class App extends Component {
+ constructor(props) {
+ super(props);
+
+ this.state = {
+ data: [],
+ isLoading: true
+ };
+ }
+
+ componentDidMount() {
+ fetch('https://reactnative.dev/movies.json')
+ .then((response) => response.json())
+ .then((json) => {
+ this.setState({ data: json.movies });
+ })
+ .catch((error) => console.error(error))
+ .finally(() => {
+ this.setState({ isLoading: false });
+ });
+ }
+
+ render() {
+ const { data, isLoading } = this.state;
+
+ return (
+
+ {isLoading ? : (
+ id}
+ renderItem={({ item }) => (
+ {item.title}, {item.releaseYear}
+ )}
+ />
+ )}
+
+ );
+ }
+};
+```
+
+
+
+
+> 默认情况下,iOS 会阻止所有 http 的请求,以督促开发者使用 https。如果你仍然需要使用 http 协议,那么首先需要添加一个 App Transport Security 的例外,详细可参考[这篇帖子](https://segmentfault.com/a/1190000002933776)。
+
+> 从 Android9 开始,也会默认阻止 http 请求,请参考[相关配置](https://blog.csdn.net/qq_40347548/article/details/86766932)
+
+## 使用其他的网络库
+
+React Native 中已经内置了[XMLHttpRequest API](https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest)(也就是俗称的 ajax)。一些基于 XMLHttpRequest 封装的第三方库也可以使用,例如[frisbee](https://github.com/niftylettuce/frisbee)或是[axios](https://github.com/mzabriskie/axios)等。但注意不能使用 jQuery,因为 jQuery 中还使用了很多浏览器中才有而 RN 中没有的东西(所以也不是所有 web 中的 ajax 库都可以直接使用)。
+
+```jsx
+const request = new XMLHttpRequest();
+request.onreadystatechange = e => {
+ if (request.readyState !== 4) {
+ return;
+ }
+
+ if (request.status === 200) {
+ console.log('success', request.responseText);
+ } else {
+ console.warn('error');
+ }
+};
+
+request.open('GET', 'https://mywebsite.com/endpoint/');
+request.send();
+```
+
+> 需要注意的是,安全机制与网页环境有所不同:在应用中你可以访问任何网站,没有[跨域](http://en.wikipedia.org/wiki/Cross-origin_resource_sharing)的限制。
+
+## WebSocket 支持
+
+React Native 还支持[WebSocket](https://developer.mozilla.org/en-US/docs/Web/API/WebSocket),这种协议可以在单个 TCP 连接上提供全双工的通信信道。
+
+```jsx
+const ws = new WebSocket('ws://host.com/path');
+
+ws.onopen = () => {
+ // connection opened
+ ws.send('something'); // send a message
+};
+
+ws.onmessage = e => {
+ // a message was received
+ console.log(e.data);
+};
+
+ws.onerror = e => {
+ // an error occurred
+ console.log(e.message);
+};
+
+ws.onclose = e => {
+ // connection closed
+ console.log(e.code, e.reason);
+};
+```
+
+## High Five!
+
+现在你的应用已经可以从各种渠道获取数据了,那么接下来面临的问题多半就是如何在不同的页面间组织和串联内容了。要管理页面的跳转,你需要学习[使用导航器跳转页面](navigation.md)。
+
+## 使用 `fetch` 和基于 cookie 的身份验证存在已知问题
+
+目前,以下选项在 `fetch` 中无法正常工作:
+
+- `redirect:manual`
+- `credentials:omit`
+
+* 在 Android 上重复使用相同名称的标头将导致仅存在最新的标头。您可以在此处找到一个临时解决方案:https://github.com/facebook/react-native/issues/18837#issuecomment-398779994。
+* 基于 cookie 的身份验证目前不稳定。您可以在此处查看引发的一些问题:https://github.com/facebook/react-native/issues/23185
+* 在 iOS 上,至少在通过 `302` 重定向时,如果存在 `Set-Cookie` 标头,则 cookie 不会正确设置。由于无法手动处理重定向,由过期会话引起的重定向可能会导致无限请求的死循环发生。
+
+## 在 iOS 上配置 NSURLSession
+
+对于一些应用程序,为在运行在 iOS 上的 React Native 应用程序中用于网络请求的底层`NSURLSession`提供自定义的`NSURLSessionConfiguration`可能是合适的。例如,可能需要为所有来自应用程序的网络请求设置自定义用户代理字符串,或者使用一个短暂的`NSURLSessionConfiguration`提供给`NSURLSession`。函数`RCTSetCustomNSURLSessionConfigurationProvider`允许进行这样的定制。记得在调用`RCTSetCustomNSURLSessionConfigurationProvider`的文件中添加以下导入:
+
+```objectivec
+#import
+```
+
+`RCTSetCustomNSURLSessionConfigurationProvider` 应在应用程序生命周期的早期调用,以便在 React 需要时可以轻松访问,例如:
+
+```objectivec
+-(void)application:(__unused UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
+ // set RCTSetCustomNSURLSessionConfigurationProvider
+ RCTSetCustomNSURLSessionConfigurationProvider(^NSURLSessionConfiguration *{
+ NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration];
+ // configure the session
+ return configuration;
+ });
+ // set up React
+ _bridge = [[RCTBridge alloc] initWithDelegate:self launchOptions:launchOptions];
+}
+```
diff --git a/cnwebsite/versioned_docs/version-0.75/new-architecture-app-intro.md b/cnwebsite/versioned_docs/version-0.75/new-architecture-app-intro.md
new file mode 100644
index 00000000000..08e126ae96b
--- /dev/null
+++ b/cnwebsite/versioned_docs/version-0.75/new-architecture-app-intro.md
@@ -0,0 +1,124 @@
+---
+id: new-architecture-app-intro
+title: 在应用中启用的预备工作
+---
+
+import NewArchitectureWarning from './\_markdown-new-architecture-warning.mdx';
+import Tabs from '@theme/Tabs';
+import TabItem from '@theme/TabItem';
+import constants from '@site/core/TabsConstants';
+
+
+
+在启用新架构之前,应先满足一些先决条件。
+
+## 更新至最新版 React Native
+
+React Native 在 0.68.0 版本中发布了对新架构的支持。
+
+本指南的撰写是基于你使用的是 [**最新发布**的 React Native 版本](https://github.com/facebook/react-native/releases/latest)。
+
+你可以在[升级到新版本](/docs/upgrading)页面找到升级说明。
+
+升级后记得重新安装依赖(运行`npm install`或`yarn`)。
+
+:::info
+
+每当你需要重命名`ios`文件夹中的某些文件时,请**使用 Xcode 重命名它们**。这可确保 Xcode 工程中的文件引用也会更新。你可能需要先清理构建文件夹(**Project**→**Clean Build Folder**或Cmd ⌘ + Shift ⇪ + K),然后重新构建应用。如果文件是在 Xcode 之外重命名的,你可能需要点击旧的`.m`文件引用,并定位到新文件。
+
+:::
+
+## Android - 启用新架构
+
+如果你已成功将项目更新到最新版本的 React Native,那么你**已经满足**在 Android 上使用新架构的所有先决条件。
+
+你只需要按如下方式更新`android/gradle.properties`文件:
+
+```diff
+# 使用此属性启用对新架构的支持。
+# 这将允许你在应用中使用TurboModules和Fabric渲染器。
+# 如果你想编写自定义TurboModules/Fabric组件或使用提供它们的库,
+# 你应该启用此标志。
+-newArchEnabled=false
++newArchEnabled=true
+```
+
+## iOS - 启用新架构
+
+如果你已成功将项目更新到最新版 React Native,那么你**已经满足**在 iOS 上使用新架构的所有先决条件。
+
+你只需通过运行带有正确标志的`pod install`来重新安装 pods:
+
+```bash
+# 运行带标志的pod install:
+RCT_NEW_ARCH_ENABLED=1 bundle exec pod install
+```
+
+## 运行应用
+
+现在是时候运行应用以验证一切正常了:
+
+
+
+
+```bash
+# 运行Android
+yarn android
+
+# 运行iOS
+yarn ios
+```
+
+
+
+
+```bash
+# 运行Android
+npm run android
+
+# 运行iOS
+npm run ios
+```
+
+
+
+
+在你的 Metro 终端日志中,你现在会看到以下日志,确认 Fabric 正在正确运行:
+
+```
+BUNDLE ./App.tsx
+LOG Running "App" with {"fabric":true,"initialProps":{"concurrentRoot": "true"},"rootTag":1}
+```
+
+## 高级 - 在互操作层中传递你的组件
+
+如果你按照前面的步骤操作,但你的应用使用了一些尚未完全迁移到新架构的自定义本地组件,你会看到一些红色/粉色框,说明该组件与 Fabric 不兼容。这是因为为旧架构编写的自定义本地组件无法在新架构中原封不动地运行。
+
+从**React Native 0.72.0**开始,我们在互操作层上做了一些工作,让你不需要等待它们迁移到新架构的情况下,就可以在新架构中使用遗留组件。
+
+你可以阅读更多关于互操作层及如何使用它的内容[这里](https://github.com/reactwg/react-native-new-architecture/discussions/135)。按照该指南注册你的组件,然后使用以下命令重新运行应用:
+
+
+
+
+```bash
+# To run android
+yarn android
+
+# To run iOS
+yarn ios
+```
+
+
+
+
+```bash
+# To run android
+npm run android
+
+# To run iOS
+npm run ios
+```
+
+
+
diff --git a/cnwebsite/versioned_docs/version-0.75/new-architecture-app-modules-ios.md b/cnwebsite/versioned_docs/version-0.75/new-architecture-app-modules-ios.md
new file mode 100644
index 00000000000..3c7b289def5
--- /dev/null
+++ b/cnwebsite/versioned_docs/version-0.75/new-architecture-app-modules-ios.md
@@ -0,0 +1,173 @@
+---
+id: new-architecture-app-modules-ios
+title: 在 iOS 上启用 TurboModule
+---
+
+import NewArchitectureWarning from './\_markdown-new-architecture-warning.mdx';
+
+
+
+Make sure your application meets all the [prerequisites](new-architecture-app-intro).
+
+## 1. Provide a TurboModuleManager Delegate
+
+Add the following imports at the top of your bridge delegate (e.g. `AppDelegate.mm`):
+
+```objc
+#import
+#import
+```
+
+You will also need to declare that your AppDelegate conforms to the `RCTTurboModuleManagerDelegate` protocol, as well as create an instance variable for our Turbo Module manager:
+
+```objc
+@interface AppDelegate () {
+ // ...
+ RCTTurboModuleManager *_turboModuleManager;
+}
+@end
+```
+
+To conform to the `RCTTurboModuleManagerDelegate` protocol, you will implement these three methods:
+
+- `getModuleClassFromName:` - This method should return the Class for a native module. You may use the `RCTCoreModulesClassProvider()` method to handle the default, core modules.
+- `getTurboModule:jsInvoker:` - This should return `nullptr`. This method may be used later to support C++ TurboModules.
+- `getModuleInstanceFromClass:moduleClass:` - This method allows you to perform any side-effects when your TurboModules are initialized. This is the TurboModule analogue to your bridge delegate’s `extraModulesForBridge` method. At this time, you’ll need to initialize the default RCTNetworking and RCTImageLoader modules as indicated below.
+
+#### TurboModuleManagerDelegate Example
+
+Take note of `getModuleInstanceFromClass:` in the following example, as it includes some necessary instantiation of several core modules that you will need to include in your application. Eventually, this may not be required.
+
+```objc title='AppDelegate.mm'
+// ...
+
+#import
+#import
+#import
+#import
+#import
+#import
+#import
+
+#import
+
+#import
+
+// ...
+
+#pragma mark RCTTurboModuleManagerDelegate
+
+- (Class)getModuleClassFromName:(const char *)name
+{
+ return RCTCoreModulesClassProvider(name);
+}
+
+- (std::shared_ptr)
+ getTurboModule:(const std::string &)name
+ jsInvoker:(std::shared_ptr)jsInvoker {
+ return nullptr;
+}
+
+- (id)getModuleInstanceFromClass:(Class)moduleClass
+{
+ // Set up the default RCTImageLoader and RCTNetworking modules.
+ if (moduleClass == RCTImageLoader.class) {
+ return [[moduleClass alloc] initWithRedirectDelegate:nil
+ loadersProvider:^NSArray> *(RCTModuleRegistry * moduleRegistry) {
+ return @ [[RCTLocalAssetImageLoader new]];
+ }
+ decodersProvider:^NSArray> *(RCTModuleRegistry * moduleRegistry) {
+ return @ [[RCTGIFImageDecoder new]];
+ }];
+ } else if (moduleClass == RCTNetworking.class) {
+ return [[moduleClass alloc]
+ initWithHandlersProvider:^NSArray> *(
+ RCTModuleRegistry *moduleRegistry) {
+ return @[
+ [RCTHTTPRequestHandler new],
+ [RCTDataRequestHandler new],
+ [RCTFileRequestHandler new],
+ ];
+ }];
+ }
+ // No custom initializer here.
+ return [moduleClass new];
+}
+```
+
+## 2. Install TurboModuleManager JavaScript Bindings
+
+Next, you will create a `RCTTurboModuleManager` in your bridge delegate’s `jsExecutorFactoryForBridge:` method, and install the JavaScript bindings:
+
+```objc
+#pragma mark - RCTCxxBridgeDelegate
+
+- (std::unique_ptr)jsExecutorFactoryForBridge:(RCTBridge *)bridge
+{
+ // Add these lines to create a TurboModuleManager
+ if (RCTTurboModuleEnabled()) {
+ _turboModuleManager =
+ [[RCTTurboModuleManager alloc] initWithBridge:bridge
+ delegate:self
+ jsInvoker:bridge.jsCallInvoker];
+
+ // Necessary to allow NativeModules to lookup TurboModules
+ [bridge setRCTTurboModuleRegistry:_turboModuleManager];
+
+ if (!RCTTurboModuleEagerInitEnabled()) {
+ /**
+ * Instantiating DevMenu has the side-effect of registering
+ * shortcuts for CMD + d, CMD + i, and CMD + n via RCTDevMenu.
+ * Therefore, when TurboModules are enabled, we must manually create this
+ * NativeModule.
+ */
+ [_turboModuleManager moduleForName:"DevMenu"];
+ }
+ }
+
+ // Add this line...
+ __weak __typeof(self) weakSelf = self;
+
+ // If you want to use the `JSCExecutorFactory`, remember to add the `#import `
+ // import statement on top.
+ return std::make_unique(
+ facebook::react::RCTJSIExecutorRuntimeInstaller([weakSelf, bridge](facebook::jsi::Runtime &runtime) {
+ if (!bridge) {
+ return;
+ }
+
+ // And add these lines to install the bindings...
+ __typeof(self) strongSelf = weakSelf;
+ if (strongSelf) {
+ facebook::react::RuntimeExecutor syncRuntimeExecutor =
+ [&](std::function &&callback) { callback(runtime); };
+ [strongSelf->_turboModuleManager installJSBindingWithRuntimeExecutor:syncRuntimeExecutor];
+ }
+ }));
+}
+```
+
+## 3. Enable TurboModule System
+
+Finally, enable TurboModules in your app by executing the following statement before React Native is initialized in your app delegate (e.g. within `didFinishLaunchingWithOptions:`):
+
+```objc
+RCTEnableTurboModule(YES);
+```
+
+#### Example
+
+```objc
+@implementation AppDelegate
+- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
+{
+ RCTEnableTurboModule(YES);
+
+ RCTBridge *bridge = [[RCTBridge alloc] initWithDelegate:self
+ launchOptions:launchOptions];
+
+ // ...
+
+ return YES;
+}
+```
diff --git a/cnwebsite/versioned_docs/version-0.75/new-architecture-app-renderer-android.md b/cnwebsite/versioned_docs/version-0.75/new-architecture-app-renderer-android.md
new file mode 100644
index 00000000000..590b7b08866
--- /dev/null
+++ b/cnwebsite/versioned_docs/version-0.75/new-architecture-app-renderer-android.md
@@ -0,0 +1,453 @@
+---
+id: new-architecture-app-renderer-android
+title: 在 Android 上启用 Fabric
+---
+
+import NewArchitectureWarning from './\_markdown-new-architecture-warning.mdx';
+
+
+
+Make sure your application meets all the [prerequisites](new-architecture-app-intro).
+
+## 1. Provide a `JSIModulePackage` inside your `ReactNativeHost`
+
+In order to enable Fabric in your app, you would need to add a `JSIModulePackage` inside your `ReactNativeHost`. If you followed the TurboModule section of this guide, you probably already know where to find your `ReactNativeHost`. If not, you can locate your `ReactNativeHost` by searching for the `getReactNativeHost()`. The `ReactNativeHost` is usually located inside your `Application` class.
+
+Once you located it, you need to add the `getJSIModulePackage` method as from the snippet below:
+
+```java title='MyApplication.java'
+public class MyApplication extends Application implements ReactApplication {
+
+ private final ReactNativeHost mReactNativeHost =
+ new ReactNativeHost(this) {
+
+ // Add those lines:
+ @Nullable
+ @Override
+ protected JSIModulePackage getJSIModulePackage() {
+ return new JSIModulePackage() {
+ @Override
+ public List getJSIModules(
+ final ReactApplicationContext reactApplicationContext,
+ final JavaScriptContextHolder jsContext) {
+ final List specs = new ArrayList<>();
+ specs.add(new JSIModuleSpec() {
+ @Override
+ public JSIModuleType getJSIModuleType() {
+ return JSIModuleType.UIManager;
+ }
+
+ @Override
+ public JSIModuleProvider getJSIModuleProvider() {
+ final ComponentFactory componentFactory = new ComponentFactory();
+ CoreComponentsRegistry.register(componentFactory);
+ final ReactInstanceManager reactInstanceManager = getReactInstanceManager();
+
+ ViewManagerRegistry viewManagerRegistry =
+ new ViewManagerRegistry(
+ reactInstanceManager.getOrCreateViewManagers(
+ reactApplicationContext));
+
+ return new FabricJSIModuleProvider(
+ reactApplicationContext,
+ componentFactory,
+ new EmptyReactNativeConfig(),
+ viewManagerRegistry);
+ }
+ });
+ return specs;
+ }
+ };
+ }
+ };
+}
+```
+
+## 2. Make sure your call `setIsFabric` on your Activity’s `ReactRootView`
+
+Inside your `Activity` class, you need to make sure you’re calling `setIsFabric` on the `ReactRootView`.
+If you don’t have a `ReactActivityDelegate` you might need to create one.
+
+```java
+public class MainActivity extends ReactActivity {
+
+ // Add the Activity Delegate, if you don't have one already.
+ public static class MainActivityDelegate extends ReactActivityDelegate {
+
+ public MainActivityDelegate(ReactActivity activity, String mainComponentName) {
+ super(activity, mainComponentName);
+ }
+
+ @Override
+ protected ReactRootView createRootView() {
+ ReactRootView reactRootView = new ReactRootView(getContext());
+
+ // Make sure to call setIsFabric(true) on your ReactRootView
+ reactRootView.setIsFabric(true);
+ return reactRootView;
+ }
+ }
+
+ // Make sure to override the `createReactActivityDelegate()` method.
+ @Override
+ protected ReactActivityDelegate createReactActivityDelegate() {
+ return new MainActivityDelegate(this, getMainComponentName());
+ }
+}
+```
+
+The crucial part in this code is the `reactRootView.setIsFabric(true)` which will enable the new renderer for this Activity.
+
+You can now verify that everything works correctly by running your android app:
+
+```bash
+yarn react-native run-android
+```
+
+In your Metro terminal log, you will now see the following log to confirm that Fabric is running correctly:
+
+```
+BUNDLE ./App.js
+LOG Running "App" with {"fabric":true,"initialProps":{},"rootTag":1}
+```
+
+## Migrating Android ViewManagers
+
+First, make sure you followed the instructions to [Enabling the New Renderer (Fabric) in Your Android Application](#enabling-the-new-renderer-fabric-in-your-android-application). Plus we will also assume that you followed the instructions from [Enabling the New NativeModule System (TurboModule) in Your Android Application](#enabling-the-new-nativemodule-system-turbomodule-in-your-android-application) as the Makefile (`Android.mk`) and other native builds setup steps are presented over there and won’t be repeated here.
+
+### JavaScript changes
+
+1. Make sure your other JS changes are ready to go by following Preparing your JavaScript codebase for the new React Native Renderer (Fabric)
+2. Replace the call to `requireNativeComponent` with `codegenNativeComponent`. This tells the JS codegen to start generating the native implementation of the component, consisting of C++ and Java classes. This is how it looks for the WebView component:
+
+```ts
+import codegenNativeComponent from 'react-native/Libraries/Utilities/codegenNativeComponent';
+
+// babel-plugin-codegen will replace the function call to use NativeComponentRegistry
+// 'RCTWebView' is interopped by RCTFabricComponentsPlugins
+
+export default (codegenNativeComponent(
+ 'RCTWebView',
+): HostComponent);
+```
+
+4. **[Flow users]** Make sure your native component has Flow types for its props, since the JS codegen uses these types to generate the type-safe native implementation of the component. The codegen generates C++ classes during the build time, which guarantees that the native implementation is always up-to-date with its JS interface. Use [these c++ compatible types](https://github.com/facebook/react-native/blob/main/Libraries/Types/CodegenTypes.js#L28-L30).
+
+```ts title="RNTMyNativeViewNativeComponent.js"
+import type {Int32} from 'react-native/Libraries/Types/CodegenTypes';
+import codegenNativeComponent from 'react-native/Libraries/Utilities/codegenNativeComponent';
+import type {HostComponent} from 'react-native';
+import type {ViewProps} from 'react-native/Libraries/Components/View/ViewPropTypes';
+
+type NativeProps = $ReadOnly<{|
+ ...ViewProps, // This is required.
+ someNumber: Int32,
+|}>;
+
+[...]
+
+export default (codegenNativeComponent(
+ 'RNTMyNativeView',
+): HostComponent);
+```
+
+5. **[TypeScript users]** We are currently investigating a support for TypeScript.
+
+### Native/Java Changes
+
+1. **Update (or Create) your ViewManager to use the generated classes from the Codegen.**
+
+Specifically you will have to implement the generated **ViewManagerInterface** and to pass events to the generated **ViewManagerDelegate.**
+Your ViewManager could follow this structure. The MyNativeView class in this example is an Android View implementation (like a subclass of LinearLayout, Button, TextView, etc.)
+
+```java title='MyNativeViewManager.java'
+// View manager for MyNativeView components.
+@ReactModule(name = MyNativeViewManager.REACT_CLASS)
+public class MyNativeViewManager extends SimpleViewManager
+ implements RNTMyNativeViewManagerInterface {
+
+ public static final String REACT_CLASS = "RNTMyNativeView";
+
+ private final ViewManagerDelegate mDelegate;
+
+ public MyNativeViewManager() {
+ mDelegate = new RNTMyNativeViewManagerDelegate<>(this);
+ }
+
+ @Nullable
+ @Override
+ protected ViewManagerDelegate getDelegate() {
+ return mDelegate;
+ }
+
+ @NonNull
+ @Override
+ public String getName() {
+ return REACT_CLASS;
+ }
+
+ @NonNull
+ @Override
+ protected MyNativeView createViewInstance(@NonNull ThemedReactContext reactContext) {
+ return new MyNativeView(reactContext);
+ }
+}
+```
+
+1. **Add your ViewManager to one of the Packages loaded by your Application.**
+
+Specifically inside the `ReactNativeHost` , update `getPackages` method to include the following:
+
+```java
+public class MyApplication extends Application implements ReactApplication {
+
+ private final ReactNativeHost mReactNativeHost = new ReactNativeHost(this) {
+ @Override
+ public boolean getUseDeveloperSupport() { /* ... */ }
+
+ @Override
+ protected List getPackages() {
+ List packages = new PackageList(this).getPackages();
+
+ // ... other packages or `TurboReactPackage added` here...
+
+ // Add those lines.
+ packages.add(new ReactPackage() {
+ @NonNull
+ @Override
+ public List createNativeModules(
+ @NonNull ReactApplicationContext reactContext) {
+ return Collections.emptyList();
+ }
+
+ @NonNull
+ @Override
+ public List createViewManagers(
+ @NonNull ReactApplicationContext reactContext) {
+ // Your ViewManager is returned here.
+ return Collections.singletonList(new MyNativeViewManager());
+ }
+ });
+ return packages;
+ }
+ };
+}
+```
+
+3. **Add a Fabric Component Registry**
+
+You need to create a new component Registry that will allow you to **register** your components to be discovered by Fabric. Let’s create the `MyComponentsRegistry` file with the following content.
+
+As you can see, some methods are `native()` which we will implement in C++ in the following paragraph.
+
+```java
+package com.awesomeproject;
+
+import com.facebook.jni.HybridData;
+import com.facebook.proguard.annotations.DoNotStrip;
+import com.facebook.react.fabric.ComponentFactory;
+import com.facebook.soloader.SoLoader;
+
+@DoNotStrip
+public class MyComponentsRegistry {
+ static {
+ SoLoader.loadLibrary("fabricjni");
+ }
+
+ @DoNotStrip private final HybridData mHybridData;
+
+ @DoNotStrip
+ private native HybridData initHybrid(ComponentFactory componentFactory);
+
+ @DoNotStrip
+ private MyComponentsRegistry(ComponentFactory componentFactory) {
+ mHybridData = initHybrid(componentFactory);
+ }
+
+ @DoNotStrip
+ public static MyComponentsRegistry register(ComponentFactory componentFactory) {
+ return new MyComponentsRegistry(componentFactory);
+ }
+}
+```
+
+4. **Register your custom Fabric Component Registry**
+
+Finally, let’s edit the `getJSIModulePackage` from the `ReactNativeHost` to also register your Component Registry alongside the Core one:
+
+```java
+public class MyApplication extends Application implements ReactApplication {
+
+ private final ReactNativeHost mReactNativeHost = new ReactNativeHost(this) {
+ @Nullable
+ @Override
+ protected JSIModulePackage getJSIModulePackage() {
+ return new JSIModulePackage() {
+ @Override
+ public List getJSIModules(
+ final ReactApplicationContext reactApplicationContext,
+ final JavaScriptContextHolder jsContext) {
+ final List specs = new ArrayList<>();
+ specs.add(new JSIModuleSpec() {
+ // ...
+
+ @Override
+ public JSIModuleProvider getJSIModuleProvider() {
+ final ComponentFactory componentFactory = new ComponentFactory();
+ CoreComponentsRegistry.register(componentFactory);
+
+ // Add this line just below CoreComponentsRegistry.register
+ MyComponentsRegistry.register(componentFactory);
+
+ // ...
+ }
+ });
+ return specs;
+ }
+ };
+ }
+ };
+}
+```
+
+### Native/C++ Changes
+
+It’s now time to provide an implementation for your `MyComponentsRegistry` in C++:
+
+1. **Create a header file: `MyComponentsRegistry.h`**
+
+The file should be placed inside the `src/main/jni` folder.
+Please note that the `kJavaDescriptor` should be adapted to follow the package name you picked for your project.
+
+```cpp title="MyComponentsRegistry.h"
+#pragma once
+
+#include
+#include
+#include
+#include
+
+namespace facebook {
+namespace react {
+
+class MyComponentsRegistry
+ : public facebook::jni::HybridClass {
+ public:
+ constexpr static auto kJavaDescriptor =
+ "Lcom/awesomeproject/MyComponentsRegistry;";
+
+ static void registerNatives();
+
+ MyComponentsRegistry(ComponentFactory *delegate);
+
+ private:
+ friend HybridBase;
+
+ static std::shared_ptr
+ sharedProviderRegistry();
+
+ const ComponentFactory *delegate_;
+
+ static jni::local_ref initHybrid(
+ jni::alias_ref,
+ ComponentFactory *delegate);
+};
+
+} // namespace react
+} // namespace facebook
+```
+
+2. **Create an implementation file: `MyComponentsRegistry.cpp`**
+
+The file should be placed inside the `src/main/jni` folder alongside `MyComponentsRegistry.h
+
+```cpp title="MyComponentsRegistry.cpp"
+#include "MyComponentsRegistry.h"
+
+#include
+#include
+#include
+#include
+#include
+
+namespace facebook {
+namespace react {
+
+MyComponentsRegistry::MyComponentsRegistry(
+ ComponentFactory *delegate)
+ : delegate_(delegate) {}
+
+std::shared_ptr
+MyComponentsRegistry::sharedProviderRegistry() {
+ auto providerRegistry = CoreComponentsRegistry::sharedProviderRegistry();
+
+ providerRegistry->add(concreteComponentDescriptorProvider<
+ RNTMyNativeViewComponentDescriptor>());
+
+ return providerRegistry;
+}
+
+jni::local_ref
+MyComponentsRegistry::initHybrid(
+ jni::alias_ref,
+ ComponentFactory *delegate) {
+ auto instance = makeCxxInstance(delegate);
+
+ auto buildRegistryFunction =
+ [](EventDispatcher::Weak const &eventDispatcher,
+ ContextContainer::Shared const &contextContainer)
+ -> ComponentDescriptorRegistry::Shared {
+ auto registry = MyComponentsRegistry::sharedProviderRegistry()
+ ->createComponentDescriptorRegistry(
+ {eventDispatcher, contextContainer});
+
+ auto mutableRegistry =
+ std::const_pointer_cast(registry);
+
+ mutableRegistry->setFallbackComponentDescriptor(
+ std::make_shared(
+ ComponentDescriptorParameters{
+ eventDispatcher, contextContainer, nullptr}));
+
+ return registry;
+ };
+
+ delegate->buildRegistryFunction = buildRegistryFunction;
+ return instance;
+}
+
+void MyComponentsRegistry::registerNatives() {
+ registerHybrid({
+ makeNativeMethod("initHybrid", MyComponentsRegistry::initHybrid),
+ });
+}
+
+} // namespace react
+} // namespace facebook
+```
+
+4. **Load your file in the OnLoad.cpp**
+
+If you followed the TurboModule instructions, you should have a `OnLoad.cpp` file inside the `src/main/jni` folder. There you should add a line to load the `MyComponentsRegistry` class:
+
+```cpp title="OnLoad.cpp"
+#include
+#include "MyApplicationTurboModuleManagerDelegate.h"
+// Add this import
+#include "MyComponentsRegistry.h"
+
+JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *) {
+ return facebook::jni::initialize(vm, [] {
+ facebook::react::MyApplicationTurboModuleManagerDelegate::registerNatives();
+
+ // Add this line
+ facebook::react::MyComponentsRegistry::registerNatives();
+ });
+}
+```
+
+You can now verify that everything works correctly by running your android app:
+
+```bash
+yarn react-native run-android
+```
diff --git a/cnwebsite/versioned_docs/version-0.75/new-architecture-app-renderer-ios.md b/cnwebsite/versioned_docs/version-0.75/new-architecture-app-renderer-ios.md
new file mode 100644
index 00000000000..c4f97d09d31
--- /dev/null
+++ b/cnwebsite/versioned_docs/version-0.75/new-architecture-app-renderer-ios.md
@@ -0,0 +1,90 @@
+---
+id: new-architecture-app-renderer-ios
+title: 在 iOS 上启用 Fabric
+---
+
+import NewArchitectureWarning from './\_markdown-new-architecture-warning.mdx';
+
+
+
+This section will go over how to enable the new renderer in your app. Make sure your application meets all the [prerequisites](new-architecture-app-intro).
+
+## 1. Enable Fabric in Podfile
+
+Add changes to your Podfile. You can see some examples in [RNTester](https://github.com/facebook/react-native/blob/main/packages/rn-tester/Podfile) and [rn-demo-app](https://github.com/facebook/fbt/blob/rn-demo-app/ios/Podfile).
+
+```ruby title="Podfile"
+# Add the following line at the top of Podfile.
+# Codegen produces files/classes that share names, and it will show the warning.
+# deterministic_uuids option surpresses the warning.
+install! 'cocoapods', :deterministic_uuids => false
+target 'Some App' do
+ pods()
+end
+def pods()
+ # Get config
+ config = use_native_modules!
+ # Use env variables to turn it on/off.
+ fabric_enabled = ENV['USE_FABRIC']
+ use_react_native!(
+ ...
+ # Modify here if your app root path isn't the same as this one.
+ :app_path => "#{Dir.pwd}/..",
+ # Pass the flag to enable fabric to use_react_native!.
+ :fabric_enabled => fabric_enabled
+ )
+end
+```
+
+## 2. Update your root view
+
+How to render your app with Fabric depends on your setup. Here is an example of how you can enable Fabric in your app with the `RN_FABRIC_ENABLED` compiler flag to enable/disable. Refer [RN-Tester’s AppDelegate](https://github.com/facebook/react-native/blob/main/packages/rn-tester/RNTester/AppDelegate.mm) as an example.
+
+```objc title="AppDelegate.mm"
+#ifdef RN_FABRIC_ENABLED
+#import
+#import
+#import
+#import
+#endif
+
+@interface AppDelegate () {
+#ifdef RN_FABRIC_ENABLED
+ RCTSurfacePresenterBridgeAdapter *_bridgeAdapter;
+ std::shared_ptr _reactNativeConfig;
+ facebook::react::ContextContainer::Shared _contextContainer;
+#endif
+
+ // Find a line that define rootView and replace/edit with the following lines.
+
+#ifdef RN_FABRIC_ENABLED
+ _contextContainer = std::make_shared();
+ _reactNativeConfig = std::make_shared();
+
+ _contextContainer->insert("ReactNativeConfig", _reactNativeConfig);
+
+ _bridgeAdapter = [[RCTSurfacePresenterBridgeAdapter alloc]
+ initWithBridge:bridge
+ contextContainer:_contextContainer];
+
+ bridge.surfacePresenter = _bridgeAdapter.surfacePresenter;
+
+ UIView *rootView =
+ [[RCTFabricSurfaceHostingProxyRootView alloc] initWithBridge:bridge
+ moduleName:<#moduleName#>
+ initialProperties:@{}];
+#else
+ // Current implementation to define rootview.
+ RCTRootView *rootView = [[RCTRootView alloc] initWithBridge:bridge
+ moduleName:<#moduleName#>
+ initialProperties:@{}];
+#endif
+```
+
+## 3. Run pod install
+
+```bash
+// Run pod install with the flags
+USE_FABRIC=1 RCT_NEW_ARCH_ENABLED=1 pod install
+```
diff --git a/cnwebsite/versioned_docs/version-0.75/new-architecture-appendix.md b/cnwebsite/versioned_docs/version-0.75/new-architecture-appendix.md
new file mode 100644
index 00000000000..6d3bd839445
--- /dev/null
+++ b/cnwebsite/versioned_docs/version-0.75/new-architecture-appendix.md
@@ -0,0 +1,301 @@
+---
+id: new-architecture-appendix
+title: Appendix
+---
+
+import NewArchitectureWarning from './\_markdown-new-architecture-warning.mdx';
+import VerticalTable from '@site/core/VerticalTable';
+
+
+
+## 一、术语
+
+整个与新架构相关的指南将遵循以下**术语**:
+
+- **传统原生组件** - 指运行在旧版 React Native 架构上的组件。
+- **传统原生模块** - 指运行在旧版 React Native 架构上的模块。
+- **Fabric 原生组件** - 指已经适配以与新架构(即新渲染器)良好协同工作的组件。为简洁起见,您可能会看到它们被称为**Fabric 组件**。
+- **Turbo 原生模块** - 指已经适配以与新架构(即新原生模块系统)良好协同工作的模块。为简洁起见,您可能会看到它们被称为**Turbo 模块**。
+
+## II. Flow 类型到原生类型的映射
+
+您可以使用以下表格作为参考,了解每个平台支持哪些类型以及它们在各个平台上的映射关系:
+
+### `string`
+
+?string],
+['Android (Java)', String],
+['iOS', NSString],
+]} />
+
+### `boolean`
+
+?boolean],
+['Android (Java)', Boolean],
+['iOS', NSNumber],
+]} />
+
+### 对象字面量
+
+比起普通的`Object`来说我们更推荐使用对象字面量,其更具有类型安全性。
+
+**示例:** `{| foo: string, ... |}`
+
+{`?{| foo: string, ...|}`}],
+['Android (Java)', '-'],
+['iOS', '-'],
+]} />
+
+### `Object`
+
+:::note
+推荐使用[对象字面量](#object-literal)。
+:::
+
+?Object],
+['Android (Java)', ReadableMap],
+['iOS', <>@{} (untyped dictionary)>],
+]} />
+
+### `Array<*>`
+
+{`?Array<*>`}],
+['Android (Java)', ReadableArray],
+['iOS', <>NSArray (or RCTConvertVecToArray when used inside objects)>],
+]} />
+
+### `Function`
+
+?Function],
+['Android (Java)', '-'],
+['iOS', '-'],
+]} />
+
+### `Promise<*>`
+
+{`?Promise<*>`}],
+['Android (Java)', com.facebook.react.bridge.Promise],
+['iOS', <>RCTPromiseResolve and RCTPromiseRejectBlock>],
+]} />
+
+### 类型联合
+
+类型联合仅支持作为回调函数。
+
+**Example:** `'SUCCESS' | 'FAIL'`
+
+
+
+### 回调函数
+
+回调函数没有类型检查,并且被泛化为`Object`。
+
+**Example:** `() =>`
+
+com.facebook.react.bridge.Callback],
+['iOS', RCTResponseSenderBlock],
+]} />
+
+:::note
+您可能还会发现参考 React Native 中核心模块的 JavaScript 规范很有用。这些规范位于 React Native 存储库中的`Libraries/`目录内。
+:::
+
+## III. TypeScript 到原生类型映射
+
+您可以使用以下表格作为参考,了解支持的类型以及它们在每个平台上的映射关系:
+
+### `string`
+
+{`string | null`}],
+['Android (Java)', String],
+['iOS', NSString],
+]} />
+
+### `boolean`
+
+{`boolean | null`}],
+['Android (Java)', Boolean],
+['iOS', NSNumber],
+]} />
+
+### `number`
+
+double],
+['iOS', NSNumber],
+]} />
+
+### Object literal
+
+This is recommended over using plain `Object`, for type safety.
+
+**Example:** `{| foo: string, ... |}`
+
+{`{| foo: string, ...|} | null`}],
+['Android (Java)', '-'],
+['iOS', '-'],
+]} />
+
+### `Object`
+
+:::note
+Recommended to use [Object literal](#object-literal-1) instead.
+:::
+
+{`Object | null`}],
+['Android (Java)', ReadableMap],
+['iOS', <>@{} (untyped dictionary)>],
+]} />
+
+### `Array<*>`
+
+{`Array<*> | null`}],
+['Android (Java)', ReadableArray],
+['iOS', <>NSArray (or RCTConvertVecToArray when used inside objects)>],
+]} />
+
+### `Function`
+
+?{`Function | null`}],
+['Android (Java)', '-'],
+['iOS', '-'],
+]} />
+
+### `Promise<*>`
+
+{`Promise<*> | null`}],
+['Android (Java)', com.facebook.react.bridge.Promise],
+['iOS', <>RCTPromiseResolve and RCTPromiseRejectBlock>],
+]} />
+
+### Type Unions
+
+Type unions are only supported as callbacks.
+
+**Example:** `'SUCCESS' | 'FAIL'`
+
+
+
+### Callbacks
+
+Callback functions are not type checked, and are generalized as `Object`s.
+
+**Example:** `() =>`
+
+com.facebook.react.bridge.Callback],
+['iOS', RCTResponseSenderBlock],
+]} />
+
+您可能还会发现参考 React Native 中核心模块的 JavaScript 规范很有用。这些规范位于 React Native 存储库的`Libraries/`目录内。
+
+## IV. 在开发过程中调用代码生成
+
+> 本节包含特定于 React Native v0.66 的信息。
+
+通常在构建时调用 Codegen,但是您可能会发现按需生成原生接口代码以进行故障排除很有用。
+
+如果您希望手动调用 codegen,有两个选项:
+
+1. 直接调用 Gradle 任务(Android)。
+2. 手动调用脚本。
+
+### Android - 直接调用 Gradle 任务
+
+您可以通过调用以下任务来触发 Codegen:
+
+```bash
+./gradlew generateCodegenArtifactsFromSchema --rerun-tasks
+```
+
+额外的 `--rerun-tasks` 标志被添加以确保 Gradle 忽略对该任务的 `UP-TO-DATE` 检查。在正常开发过程中,您不应该需要它。
+
+`generateCodegenArtifactsFromSchema` 任务通常在 `preBuild` 任务之前运行,因此您不需要手动调用它,但它将在构建之前触发。
+
+### 手动调用脚本
+
+或者,您可以直接调用 Codegen,绕过 Gradle 插件或 CocoaPods 基础设施。
+可以使用以下命令完成此操作。
+
+现在您已经配置了 Gradle 插件或 CocoaPods 库,所以要提供的参数看起来会非常熟悉。
+
+#### 生成模式文件
+
+首先,您需要从 JavaScript 源代码中生成一个模式文件。只有在 JavaScript 规范发生更改时才需要执行此操作。生成此模式的脚本作为`react-native-codegen`包的一部分提供。如果在 React Native 应用程序内运行此脚本,可以直接使用位于`node_modules`目录下的该包:
+
+```bash
+node node_modules/react-native-codegen/lib/cli/combine/combine-js-to-schema-cli.js \
+
+```
+
+> `react-native-codegen`的源代码可在 React Native 存储库中找到,位于`packages/react-native-codegen`目录下。如果需要从源代码构建自己的`react-native-codegen`包,请在该目录中运行 `yarn install` 和 `yarn build`. 在大多数情况下,您不需要这样做。
+
+#### 生成原生代码构件
+
+一旦您拥有用于本地模块或组件的架构文件,您可以使用第二个脚本为库生成实际的原生代码构件。您可以使用前一个脚本生成的相同架构文件。
+
+```bash
+node node_modules/react-native/scripts/generate-specs-cli.js \
+ --platform \
+ --schemaPath \
+ --outputDir \
+ [--libraryName library_name] \
+ [--javaPackageName java_package_name] \
+ [--libraryType all(default)|modules|components]
+```
+
+> **注意:** Codegen 的输出构件位于 build 文件夹中,不应提交到版本控制系统。
+> 它们仅供参考。
+
+##### 示例
+
+以下是调用 Codegen 脚本的基本示例,用于为提供原生模块的库生成原生 iOS 界面代码。此库的 JavaScript 规范源文件位于`js/`子目录中,而该库的原生代码期望在`ios`子目录中可用原生接口。
+
+```bash
+# 生成模式 - 仅在JS规范更改时需要执行
+node node_modules/react-native-codegen/lib/cli/combine/combine-js-to-schema-cli.js /tmp/schema.json ./js
+
+# 生成原生代码构件
+node node_modules/react-native/scripts/generate-specs-cli.js \
+ --platform ios \
+ --schemaPath /tmp/schema.json \
+ --outputDir ./ios \
+ --libraryName MyLibSpecs \
+ --libraryType modules
+```
+
+在上面的示例中,代码生成脚本将会生成几个文件:`MyLibSpecs.h` 和 `MyLibSpecs-generated.mm`,以及一些 `.h` 和 `.cpp` 文件,全部位于 `ios` 目录下。
+
+## V. 关于现有应用的注意事项
+
+本指南提供了迁移基于 React Native 提供的默认应用模板的应用程序的说明。如果您的应用程序与模板有所偏离,或者您正在使用从未基于该模板构建过的应用程序,则以下部分可能会对您有所帮助。
+
+### 查找桥接代理
+
+本指南假设`AppDelegate`被配置为桥接代理。如果您不确定哪个是您的桥接代理,请在`RCTBridge`和`RCTCxxBridge`中设置断点,运行您的应用,并检查 `self.delegate`.
diff --git a/cnwebsite/versioned_docs/version-0.75/new-architecture-intro.md b/cnwebsite/versioned_docs/version-0.75/new-architecture-intro.md
new file mode 100644
index 00000000000..fc216a8018d
--- /dev/null
+++ b/cnwebsite/versioned_docs/version-0.75/new-architecture-intro.md
@@ -0,0 +1,33 @@
+---
+id: new-architecture-intro
+title: 迁移到新架构
+---
+
+import NewArchitectureWarning from './\_markdown-new-architecture-warning.mdx';
+
+
+
+# 入门新架构
+
+此迁移指南旨在为React Native的**库作者**和**应用程序开发者**提供。它概述了您需要遵循的步骤,以在您的**Android**和**iOS**库和应用中使用由**新的NativeModule系统(TurboModule)和新的渲染器(Fabric)**组成的新架构。
+
+## 目录
+
+本指南分为五个部分:
+
+- **在第三方库中支持新架构**
+ - [在JavaScript中支持新架构的预备工作](new-architecture-library-intro)
+ - 在库中启用新架构
+ - [Android](new-architecture-library-android)
+ - [iOS](new-architecture-library-ios)
+- **在应用中支持新架构**
+ - [在应用中支持新架构的预备工作](new-architecture-app-intro)
+ - 在应用中启用新的NativeModule系统(TurboModule)
+ - [Android](new-architecture-app-modules-android)
+ - [iOS](new-architecture-app-modules-ios)
+ - 在应用中启用新的渲染器(Fabric)
+ - [Android](new-architecture-app-renderer-android)
+ - [iOS](new-architecture-app-renderer-ios)
+- [**React 18和React Native**](react-18-and-react-native)
+- [**故障排除**](new-architecture-troubleshooting)
+- [**附录**](new-architecture-appendix)
diff --git a/cnwebsite/versioned_docs/version-0.75/new-architecture-library-android.md b/cnwebsite/versioned_docs/version-0.75/new-architecture-library-android.md
new file mode 100644
index 00000000000..49d4b77d70c
--- /dev/null
+++ b/cnwebsite/versioned_docs/version-0.75/new-architecture-library-android.md
@@ -0,0 +1,118 @@
+---
+id: new-architecture-library-android
+title: 在 Android 库中启用
+---
+
+import NewArchitectureWarning from './\_markdown-new-architecture-warning.mdx'; import Tabs from '@theme/Tabs'; import TabItem from '@theme/TabItem'; import constants from '@site/core/TabsConstants';
+
+
+
+一旦您在[先决条件](new-architecture-library-intro)中定义了本机模块的 JavaScript 规范,设置了 CodeGen 配置,并遵循了 Android/Gradle 设置,然后就可以将您的库迁移到新架构。以下是迁移所需的步骤。
+
+## 1. 扩展或实现代码生成的本地接口
+
+您为原生模块或组件定义的 JavaScript 规范将用于为每个支持的平台(即 Android 和 iOS)生成本地接口代码。这些本地接口文件将在构建依赖于您的库的反应应用程序时**生成**。
+
+虽然这种生成的本地接口代码**不会作为您图书馆的一部分进行运输**,但您确实需要确保您的 Java / Kotlin 代码符合这些本地接口文件提供的协议。
+
+您可以调用`generateCodegenArtifactsFromSchema` Gradle 任务来为您的库生成本机接口代码,以便将其用作**参考:**
+
+```bash
+./gradlew generateCodegenArtifactsFromSchema
+```
+
+The files that are output can be found inside `build/generated/source/codegen` and **should not be committed**, but you’ll need to refer to them to determine what changes you need to make to your native modules in order for them to provide an implementation for each generated interface.
+
+The output of the Codegen for a module called `NativeAwesomeManager` will look like this:
+
+```
+app/build/generated/source/codegen
+├── java
+│ └── com
+│ └── example
+│ └── samplelibrary
+│ └── NativeAwesomeManagerSpec.java
+├── jni
+│ ├── Android.mk
+│ ├── CMakeLists.txt
+│ ├── react
+│ │ └── renderer
+│ │ └── components
+│ │ └── samplelibrary
+│ │ ├── ComponentDescriptors.h
+│ │ ├── EventEmitters.cpp
+│ │ ├── EventEmitters.h
+│ │ ├── Props.cpp
+│ │ ├── Props.h
+│ │ ├── ShadowNodes.cpp
+│ │ └── ShadowNodes.h
+│ ├── samplelibrary-generated.cpp
+│ └── samplelibrary.h
+└── schema.json
+```
+
+### Extends the Abstract Class Provided by the Codegen
+
+Update your native module or component to ensure it **extends the abstract class** that has been code-generated from your JavaScript specs (i.e., the `NativeAwesomeManagerSpec.java` file from the previous example).
+
+Following the example set forth in the previous section, your library might import `NativeAwesomeManagerSpec`, implement the relevant native interface and the necessary methods for it:
+
+
+
+
+
+```java
+import androidx.annotation.NonNull;
+
+import com.example.samplelibrary.NativeAwesomeManagerSpec;
+import com.facebook.react.bridge.Promise;
+import com.facebook.react.bridge.ReactApplicationContext;
+
+public class NativeAwesomeManager extends NativeAwesomeManagerSpec {
+
+ public static final String NAME = "NativeAwesomeManager";
+
+ public NativeAwesomeManager(ReactApplicationContext reactContext) {
+ super(reactContext);
+ }
+
+ @Override
+ public void getString(String id, Promise promise) {
+ // Implement this method
+ }
+
+ @NonNull
+ @Override
+ public String getName() {
+ return NAME;
+ }
+}
+```
+
+
+
+
+
+```kotlin
+import com.example.samplelibrary.NativeAwesomeManagerSpec
+import com.facebook.react.bridge.Promise
+import com.facebook.react.bridge.ReactApplicationContext
+
+class NativeAwesomeManager(reactContext: ReactApplicationContext) :
+ NativeAwesomeManagerSpec(reactContext) {
+ override fun getString(id: String, promise: Promise) {
+ // Implement this method
+ }
+
+ override fun getName() = NAME
+
+ companion object {
+ val NAME = "NativeAwesomeManager"
+ }
+}
+```
+
+
+
+
+Please note that the **generated abstract class** that you’re now extending (`MyAwesomeSpec` in this example) is itself extending `ReactContextBaseJavaModule`. Therefore you should not lose access to any of the method/fields you were previously using (e.g., the `ReactApplicationContext` and so on). Moreover, the generated class will now also implement the `TurboModule` interface for you.
diff --git a/cnwebsite/versioned_docs/version-0.75/new-architecture-library-intro.md b/cnwebsite/versioned_docs/version-0.75/new-architecture-library-intro.md
new file mode 100644
index 00000000000..2116ca8d2f4
--- /dev/null
+++ b/cnwebsite/versioned_docs/version-0.75/new-architecture-library-intro.md
@@ -0,0 +1,555 @@
+---
+id: new-architecture-library-intro
+title: 在库中启用的预备工作
+---
+
+import Tabs from '@theme/Tabs';
+import TabItem from '@theme/TabItem';
+import constants from '@site/core/TabsConstants';
+import NewArchitectureWarning from './\_markdown-new-architecture-warning.mdx';
+
+
+
+The following steps will help ensure your modules and components are ready for the New Architecture.
+
+## Define Specs in JavaScript
+
+The JavaScript specs serve as the source of truth for the methods provided by each native module. They define all APIs provided by the native module, along with the types of those constants and functions.
+Using a **typed** spec file allows you to be intentional and declare all the input arguments and outputs of your native module’s methods.
+
+:::info
+**TypeScript** support is in beta right now.
+:::
+
+To adopt the New Architecture, you start by creating these specs for your native modules and native components. You can do this before migrating to the New Architecture: the specs will be used later on to generate native interface code for all the supported platforms as a way to enforce uniform APIs across platforms.
+
+#### Turbo Native Modules
+
+JavaScript spec files **must** be named `Native.js`, and they export a `TurboModuleRegistry` `Spec` object. The name convention is important because the Codegen process looks for modules whose `js` (`jsx`, `ts`, or `tsx`) spec file starts with the keyword `Native`.
+
+The following is a basic JavaScript spec template, written using the [Flow](https://flow.org/) and [TypeScript](https://www.typescriptlang.org/) syntax.
+
+
+
+
+```ts
+// @flow
+
+import type {TurboModule} from 'react-native/Libraries/TurboModule/RCTExport';
+import {TurboModuleRegistry} from 'react-native';
+
+export interface Spec extends TurboModule {
+ +getConstants: () => {||};
+
+ // your module methods go here, for example:
+ getString(id: string): Promise;
+}
+
+export default (TurboModuleRegistry.get(''): ?Spec);
+```
+
+
+
+
+```ts
+import type {TurboModule} from 'react-native';
+import {TurboModuleRegistry} from 'react-native';
+
+export interface Spec extends TurboModule {
+ readonly getConstants: () => {};
+
+ // your module methods go here, for example:
+ getString(id: string): Promise;
+}
+
+export default TurboModuleRegistry.get('');
+```
+
+
+
+
+#### Fabric Native Components
+
+JavaScript spec files **must** be named `NativeComponent.js` (for TypeScript use extension `.ts` or `.tsx`) and they export a `HostComponent` object. The name convention is important: the Codegen process looks for components whose spec file (either JavaScript or TypeScript) ends with the suffix `NativeComponent`.
+
+The following snippet shows a basic JavaScript spec template, written in [Flow](https://flow.org/) as well as [TypeScript](https://www.typescriptlang.org/).
+
+
+
+
+```ts
+// @flow strict-local
+
+import type {ViewProps} from 'react-native/Libraries/Components/View/ViewPropTypes';
+import type {HostComponent} from 'react-native';
+import codegenNativeComponent from 'react-native/Libraries/Utilities/codegenNativeComponent';
+
+type NativeProps = $ReadOnly<{|
+ ...ViewProps,
+ // add other props here
+|}>;
+
+export default (codegenNativeComponent(
+ '',
+): HostComponent);
+```
+
+
+
+
+```ts
+import type {ViewProps} from 'ViewPropTypes';
+import type {HostComponent} from 'react-native';
+import codegenNativeComponent from 'react-native/Libraries/Utilities/codegenNativeComponent';
+
+export interface NativeProps extends ViewProps {
+ // add other props here
+}
+
+export default codegenNativeComponent(
+ '',
+) as HostComponent;
+```
+
+
+
+
+### Supported Types
+
+When using Flow or TypeScript, you will be using [type annotations](https://flow.org/en/docs/types/) to define your spec. Keeping in mind that the goal of defining a JavaScript spec is to ensure the generated native interface code is type-safe, the set of supported types will be those that can be mapped one-to-one to a corresponding type on the native platform.
+
+
+
+In general, this means you can use primitive types (strings, numbers, booleans), function types, object types, and array types. Union types, on the other hand, are not supported. All types must be read-only. For Flow: either `+` or `$ReadOnly<>` or `{||}` objects. For TypeScript: `readonly` for properties, `Readonly<>` for objects, and `ReadonlyArray<>` for arrays.
+
+> See Appendix [II. Flow Type to Native Type Mapping](new-architecture-appendix#ii-flow-type-to-native-type-mapping).
+> See Appendix [III. TypeScript to Native Type Mapping](new-architecture-appendix#iii-typescript-to-native-type-mapping).
+
+### Codegen Helper Types
+
+You can use predefined types for your JavaScript spec, here is a list of them:
+
+- `Double`
+- `Float`
+- `Int32`
+- `WithDefault` - Sets default value for type
+- `BubblingEventHandler` - For bubbling events (eg: `onChange`).
+- `DirectEventHandler` - For direct events (eg: `onClick`).
+
+Later on those types are compiled to coresponding equivalents on target platforms.
+
+### Be Consistent Across Platforms and Eliminate Type Ambiguity
+
+Before adopting the New Architecture in your native module, you should ensure your methods are consistent across platforms. You will realize this as you set out to write the JavaScript spec for your native module - remember that JavaScript spec defines what the methods will look like on all supported platforms.
+
+If your existing native module has methods with the same name on multiple platforms, but with different numbers or types of arguments across platforms, you will need to find a way to make these consistent. If you have methods that can take two or more different types for the same argument, then you need to find a way to resolve this type of ambiguity as type unions are intentionally not supported.
+
+## Make Sure _autolinking_ is Enabled
+
+
+
+[Autolinking](https://github.com/react-native-community/cli/blob/master/docs/autolinking.md) is a feature of the React Native CLI that simplifies the installation of third-party React Native libraries. Instructions to enable _autolinking_ are available in the [React Native CLI docs](https://github.com/react-native-community/cli/blob/master/docs/autolinking.md).
+
+### Android
+
+On Android, this generally requires you to include `native_modules.gradle` in both your `settings.gradle` and `build.gradle`.
+
+If you used the default template provided with React Native (i.e., `yarn react-native init `), then autolinking is already enabled.
+
+You can anyway verify that you have it enabled with:
+
+```bash
+$ grep -r "native_modules.gradle" android
+
+android/app/build.gradle:apply from: file("../../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesAppBuildGradle(project)
+android/settings.gradle:apply from: file("../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesSettingsGradle(settings)
+...
+```
+
+If you don't, open the `settings.gradle` file and add this line:
+
+```diff
+rootProject.name =
++ apply from: file("../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesSettingsGradle(settings)
+```
+
+Then, open your `android/app/build.gradle` file and add this line at the end of the file:
+
+```kotlin
+apply from: file("../../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesAppBuildGradle(project)
+```
+
+### iOS
+
+On iOS, make sure that your library provides a Podspec (see [`react-native-webview`](https://github.com/react-native-community/react-native-webview/blob/master/react-native-webview.podspec) for an example).
+
+:::info
+
+To determine if your library is set up for autolinking, check the CocoaPods output after running `pod install` (or `arch -x86_64 pod install` in case of a Mac M1) on an iOS project. If you see "auto linking library name", you are all set to go.
+
+:::
+
+## Configure Codegen
+
+[Codegen](the-new-architecture/pillars-codegen) is a tool that runs when you build an Android app or install the dependencies of an iOS app. It creates some scaffolding code that you won't have to create manually.
+
+Codegen can be configured in the `package.json` file of your Library. Add the following JSON object at the end of it.
+
+```diff
+ },
++ "codegenConfig": {
++ "name": "",
++ "type": "all",
++ "jsSrcsDir": ".",
++ "android": {
++ "javaPackageName": "com.facebook.fbreact.specs"
++ }
++ }
+}
+```
+
+- The `codegenConfig` is the key used by the Codegen to verify that there is some code to generate.
+- The `name` field is the name of the library.
+- The `type` field is used to identify the type of module we want to create. We suggest keeping `all` to support libraries that contain both Turbo Native Module and Fabric Native Components.
+- The `jsSrcsDir` is the directory where the codegen will start looking for JavaScript specs.
+- The `android.javaPackageName` is the name of the package where the generated code ends up.
+
+Android also requires to have the [React Gradle Plugin properly configured](new-architecture-app-intro#android-specifics) in your app.
+
+## Migrating from `UIManager` JavaScript APIs
+
+In the New Architecture, most `UIManager` methods will become available as instance methods on native component instances obtained via `ref`:
+
+```ts
+function MyComponent(props: Props) {
+ const viewRef = useRef(null);
+
+ useEffect(() => {
+ viewRef.current.measure(((left, top, width, height, pageX, pageY) => {
+ // ...
+ });
+ }, []);
+
+ return ;
+}
+```
+
+This new API design provides several benefits:
+
+- Better developer ergonomics by removing the need for separately importing `UIManager` or calling `findNodeHandle`.
+- Better performance by avoiding the node handle lookup step.
+- Directionally aligned with [the analogous deprecation of `findDOMNode`](https://reactjs.org/docs/strict-mode.html#warning-about-deprecated-finddomnode-usage).
+
+We will eventually deprecate `UIManager`. However, we recognize that migrations demand a high cost for many application and library authors. In order to minimize this cost, we plan to continue supporting as many of the methods on `UIManager` as possible in the New Architecture.
+
+**Support for `UIManager` methods in the New Architecture is actively being developed.** While we make progress here, early adopters can still experiment with the New Architecture by following these steps to migrate off common `UIManager` APIs:
+
+1. Migrating off `setNativeProps`
+2. Move the call to `requireNativeComponent` to a separate file
+3. Migrating off `dispatchViewManagerCommand`
+4. Creating NativeCommands with `codegenNativeCommands`
+
+### Migrating off `setNativeProps`
+
+`setNativeProps` will not be supported in the post-Fabric world. To migrate, move all `setNativeProp` values to component state.
+
+**Example**
+
+```ts
+class MyComponent extends React.Component {
+ _viewRef: ?React.ElementRef;
+
+ render() {
+ const {somePropValue} = this.props;
+ return
+ }
+
+ _captureRef: (ref: React.ElementRef) => {
+ this._viewRef = ref;
+ }
+
+ _onSubmit: () => {
+ this._viewRef.setNativeProps({
+ style: styles.submittedView,
+ accessibility: true
+ });
+ // ...other logic for onSubmit
+ }
+}
+
+const styles = StyleSheet.create({
+ view: {backgroundColor: 'white'},
+ submittedView: {borderWidth: 1}
+});
+```
+
+In this example, when the View is pressed, there is a `setNativeProps` call to update the style and accessibility props of the component. To migrate this component, it’s important to understand its current behavior using `setNativeProps`.
+
+#### Pre-Fabric, Component Props Persist
+
+On the first render, the component props are those declared in the render function. After the View is pressed `_onSubmit` calls `setNativeProps` with updated prop values.
+The resulting component can be represented as such:
+
+```tsx
+
+```
+
+Note that all prop values set in the render function are unchanged even though `setNativeProps` didn’t pass those props. Also, `style` is now the merged value of its value prior to `_onSubmit` and `styles.submittedView`. This is the important takeaway: in our current pre-Fabric world, **component props persist.** The platform view caches the prop values it's passed from the JS side. If this wasn’t the case, then following the setNativeProps call, React Native would have rendered a component like this:
+
+```tsx
+
+```
+
+The fact that React Native stores some internal state of each component that isn’t explicitly declared in the last render is what Fabric intends to fix.
+
+#### Moving `setNativeProps` to state
+
+Taking the above caveats into account, a proper migration would look like this:
+
+```tsx
+class MyComponent extends React.Component {
+ state = {
+ hasSubmitted: false,
+ accessibility: false
+ };
+
+ render() {
+ const {somePropValue} = this.props;
+ const submittedStyle = this.state.hasSubmitted ? styles.submittedView: null;
+ return
+ }
+
+ _onSubmit: () => {
+ this.setState(state => ({...state, hasSubmitted: true}));
+ // ...other logic for onSubmit
+ }
+}
+
+
+const styles = StyleSheet.create({
+ view: {backgroundColor: 'white'},
+ submittedView: {borderWidth: 1}
+});
+```
+
+- We are using the `hasSubmitted` flag to represent whether or not we want to apply `styles.submittedView`. If the style was dynamic, then it makes sense to store the style object in state.
+- `accessibility` is now explicitly passed to the View component as a boolean. This differs from the prior implementation where `accessibility` wasn’t passed as a prop in the initial render, but in this case, we know the non-specification of `accessibility` is handled in the same way as `accessibilty={false}`.
+
+Be wary of your assumptions, as uncaught subtleties can introduce differences in behavior! It’s a good idea to have snapshot tests of your component as they will highlight any differences pre and post your migration.
+
+### Move the call to `requireNativeComponent` to a separate file
+
+This will prepare for the JS to be ready for the new codegen system for the New Architecture. The new file should be named `NativeComponent.js.`
+
+#### Old way
+
+```js
+const RNTMyNativeView = requireNativeComponent('RNTMyNativeView');
+
+[...]
+
+return ;
+```
+
+#### New way
+
+```tsx title="RNTMyNativeNativeComponent.tsx"
+import RNTMyNativeViewNativeComponent from './RNTMyNativeViewNativeComponent';
+
+[...]
+
+return ;
+```
+
+```tsx title="RNTMyNativeViewNativeComponent.tsx"
+import {requireNativeComponent} from 'react-native';
+
+const RNTMyNativeViewNativeComponent = requireNativeComponent(
+ 'RNTMyNativeView',
+);
+
+export default RNTMyNativeViewNativeComponent;
+```
+
+#### Flow support
+
+If `requireNativeComponent` is not typed, you can temporarily use the `mixed` type to fix the Flow warning, for example:
+
+```js
+import type {HostComponent} from 'react-native/Libraries/Renderer/shims/ReactNativeTypes';
+// ...
+const RCTWebViewNativeComponent: HostComponent =
+ requireNativeComponent < mixed > 'RNTMyNativeView';
+```
+
+#### Later on you can replace `requireNativeComponent`
+
+When you are ready to migrate to Fabric you can replace `requireNativeComponent` with `codegenNativeComponent`:
+
+```ts title="RNTMyNativeViewNativeComponent.ts"
+export default (codegenNativeComponent(
+ 'RNTMyNativeView',
+): HostComponent);
+```
+
+And update the main file:
+
+```ts title="RNTMyNativeNativeComponent.ts"
+export default require('./RNTMyNativeViewNativeComponent')
+ .default;
+```
+
+### Migrating off `dispatchViewManagerCommand`
+
+Similar to the one above, in an effort to avoid calling methods on the UIManager, all view manager methods are now called through an instance of `NativeCommands`. `codegenNativeCommands` is a new API to code-generate `NativeCommands` given an interface of your view manager’s commands.
+
+**Before**
+
+```tsx
+class MyComponent extends React.Component {
+ _moveToRegion: (region: Region, duration: number) => {
+ UIManager.dispatchViewManagerCommand(
+ ReactNative.findNodeHandle(this),
+ 'moveToRegion',
+ [region, duration]
+ );
+ }
+
+ render() {
+ return
+ }
+}
+```
+
+**Creating NativeCommands with `codegenNativeCommands`**
+
+```ts title="MyCustomMapNativeComponent.ts"
+import codegenNativeCommands from 'react-native/Libraries/Utilities/codegenNativeCommands';
+import type {HostComponent} from 'react-native/Libraries/Renderer/shims/ReactNativeTypes';
+
+type MyCustomMapNativeComponentType = HostComponent;
+
+interface NativeCommands {
+ +moveToRegion: (
+ viewRef: React.ElementRef