Skip to content

Commit

Permalink
Checks for the documentation (#3348)
Browse files Browse the repository at this point in the history
  • Loading branch information
arati-1 authored Sep 28, 2022
1 parent 3d1ea2c commit d6fe39d
Show file tree
Hide file tree
Showing 3 changed files with 21 additions and 21 deletions.
2 changes: 1 addition & 1 deletion docs/new-architecture-intro.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import NewArchitectureWarning from './\_markdown-new-architecture-warning.mdx';

# Getting Started with the New Architecture

This migration guide is designed for React Native **library authors** and **application developers**. It outlines the steps you need to follow to roll out the new Architecture, composed by the **New Native Module system (Turbo Module) and the new Renderer (Fabric)** to your **Android** and **iOS** libraries and apps.
This migration guide is designed for React Native **library authors** and **application developers**. It outlines the steps you need to follow to roll out the new Architecture, composed of the **new NativeModule system (Turbo Module) and the new Renderer (Fabric)** to your **Android** and **iOS** libraries and apps.

## Table of Contents

Expand Down
38 changes: 19 additions & 19 deletions docs/new-architecture-library-intro.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,20 +14,20 @@ The following steps will help ensure your modules and components are ready for t

## Define Specs in JavaScript

The JavaScript specs serve as the source of truth for the methods that are provided by each native module. They define all APIs that are provided by the native module, along with the types of those constants and functions.
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 prior to actually 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.
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<MODULE_NAME>.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`.
JavaScript spec files **must** be named `Native<MODULE_NAME>.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/) syntax as well as [TypeScript](https://www.typescriptlang.org/).
The following is a basic JavaScript spec template, written using the [Flow](https://flow.org/) and [TypeScript](https://www.typescriptlang.org/) syntax.

<Tabs groupId="fabric-component-backward-compatibility"
defaultValue={constants.defaultFabricComponentSpecLanguage}
Expand Down Expand Up @@ -120,11 +120,11 @@ export default codegenNativeComponent<NativeProps>(
### 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.
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.
<!-- alex ignore primitive -->
In general, this means you can use primitive types (strings, numbers, booleans), and 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.
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).
Expand All @@ -144,9 +144,9 @@ Later on those types are compiled to coresponding equivalents on target platform
### Be Consistent Across Platforms and Eliminate Type Ambiguity
Before adopting the New Architecture in your native module, you will need to ensure your methods are consistent across platforms. This is something you will realize 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.
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, you will also need to find a way to resolve this type of ambiguity as type unions are intentionally not supported.
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
Expand All @@ -158,7 +158,7 @@ If your existing native module has methods with the same name on multiple platfo
On Android, this generally requires you to include `native_modules.gradle` in both your `settings.gradle[.kts]` and `build.gradle[.kts]`.
If you used the default template provided with React Native (i.e. you used `yarn react-native init <Project>`), then you have autolinking already enabled.
If you used the default template provided with React Native (i.e., `yarn react-native init <Project>`), then autolinking is already enabled.
You can anyway verify that you have it enabled with:
Expand Down Expand Up @@ -214,17 +214,17 @@ Codegen can be configured in the `package.json` file of your Library. Add the fo
- 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. Our suggestion is to keep `all` to support libraries that contain both Turbo Native Module and Fabric Native Components.
- 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 wil end up.
- 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.
## Preparing your JavaScript Codebase for the new React Native Renderer (Fabric)
The new renderer, Fabric, doesn’t use the UIManager, so direct calls to UIManager will need to be migrated. Historically, calls to UIManager had some pretty complicated patterns. Fortunately, we’ve created new APIs that are much cleaner. These new APIs are forward compatible with Fabric, so you can migrate your code today, and the APIs will work properly when you turn on Fabric!
Fabric will be providing new type safe JS APIs that are much more ergonomic than some of the patterns we've seen in product code today. These APIs require references to the underlying component, no longer using the result of `findNodeHandle`. `findNodeHandle` is used to search the tree for a native component given a class instance. This was breaking the React abstraction model. `findNodeHandle` is not compatible with React 18. Deprecation of `findNodeHandle` in React Native is similar to the [deprecation of `findDOMNode` in React DOM](https://reactjs.org/docs/strict-mode.html#warning-about-deprecated-finddomnode-usage).
Fabric will be providing new type-safe JS APIs that are much more ergonomic than some of the patterns we've seen in product code today. These APIs require references to the underlying component, no longer using the result of `findNodeHandle`. `findNodeHandle` is used to search the tree for a native component given a class instance. This was breaking the React abstraction model. `findNodeHandle` is not compatible with React 18. Deprecation of `findNodeHandle` in React Native is similar to the [deprecation of `findDOMNode` in React DOM](https://reactjs.org/docs/strict-mode.html#warning-about-deprecated-finddomnode-usage).
While we know that all deprecations are a hassle, this guide is intended to help people update components as smoothly as possible. Here are the steps you need to take to get your JS codebase ready for Fabric:
Expand All @@ -237,7 +237,7 @@ While we know that all deprecations are a hassle, this guide is intended to help
### Migrating `findNodeHandle` / getting a `HostComponent`
Much of the migration work requires a HostComponent ref to access certain APIs that are only attached to host components (like View, Text, or ScrollView). HostComponents are the return value of calls to `requireNativeComponent`. `findNodeHandle` tunnels through multiple levels of component hierarchy to find the nearest native component.
Most of the migration work requires a HostComponent ref to access certain APIs that are only attached to host components (like View, Text, or ScrollView). HostComponents are the return value of calls to `requireNativeComponent`. `findNodeHandle` tunnels through multiple levels of component hierarchy to find the nearest native component.
As a concrete example, this code uses `findNodeHandle` to tunnel from `ParentComponent` through to the `View` rendered by `ChildComponent`.
Expand Down Expand Up @@ -275,7 +275,7 @@ class ChildComponent extends React.Component<Props> {
We can’t convert this call to `this._ref.measure` because `this._ref` is an instance to `ChildComponent`, which is not a HostComponent and thus does not have a `measure` function.
`ChildComponent` renders a `View`, which is a HostComponent, so we need to get a reference to `View` instead. There are typically two approaches to get what we need. If the component we need to get the ref from is a function component, using `forwardRef` is probably the right choice. If it is a class component with other public methods, adding a public method for getting the ref is an option. Here are examples of those two forms:
`ChildComponent` renders a `View`, which is a HostComponent, so we need to get a reference to `View` instead. There are typically two approaches to getting what we need. If the component we need to get the ref from is a function component, using `forwardRef` is probably the right choice. If it is a class component with other public methods, adding a public method for getting the ref is an option. Here are examples of those two forms:
#### Using `forwardRef`
Expand Down Expand Up @@ -429,17 +429,17 @@ The resulting component can be represented as such:
/>
```

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 its 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:
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:

```jsx
<View accessibility={true} style={styles.submittedView} />
```

The fact that React Native stores some internal state of each component that isn’t explicitly declared in last render is what Fabric intends to fix.
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 those caveats into account, a proper migration would look like this:
Taking the above caveats into account, a proper migration would look like this:

```tsx
class MyComponent extends React.Component<Props> {
Expand Down Expand Up @@ -471,8 +471,8 @@ const styles = StyleSheet.create({
});
```
- 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}`
- 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.
Expand Down
2 changes: 1 addition & 1 deletion docs/new-architecture-library-ios.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ If you need to explicitly know which `folly_flags` React Native is using, you ca

The JavaScript spec for your native module or component will be used to generate native interface code for each supported platform (i.e., Android and iOS). These native interface files will be generated when a React Native application that depends on your library is built.

While this generated native interface code **will not ship as part of your library**, you do need to make sure your Objective-C or Java code conforms to the protocols provided by these native interface files. You can use the Codegen script to generate your library’s native interface code in order to use it **as reference**.
While this generated native interface code **will not ship as part of your library**, you do need to make sure your Objective-C or Java code conforms to the protocols provided by these native interface files. You can use the Codegen script to generate your library’s native interface code in order to use it **as a reference**.

```sh
cd <path/to/your/app>
Expand Down

0 comments on commit d6fe39d

Please sign in to comment.