Skip to content

new-arch code formatting and small tweaks #2922

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
Jan 14, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 15 additions & 3 deletions docs/new-architecture-app-intro.md
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,11 @@ Hermes is an open-source JavaScript engine optimized for React Native. We highly

Please [follow the instructions on the React Native website](hermes) in order to enable Hermes in your application.

> iOS: If you opt out of using Hermes, you will need to replace `HermesExecutorFactory` with `JSCExecutorFactory` in any examples used throughout the rest of this playbook.
:::caution

**iOS:** If you opt out of using Hermes, you will need to replace `HermesExecutorFactory` with `JSCExecutorFactory` in any examples used throughout the rest of this playbook.

:::

## iOS: Enable C++17 language feature support

Expand All @@ -132,13 +136,21 @@ If done correctly, your diff will show the following changes to your project fil
CLANG_CXX_LANGUAGE_STANDARD = "c++17"
```

> Your project should also be configured to support Folly. This should be done automatically once the library dependency is picked up, so no further changes to your project are necessary.
:::info

Your project should also be configured to support Folly. This should be done automatically once the library dependency is picked up, so no further changes to your project are necessary.

:::

## iOS: Use Objective-C++ (`.mm` extension)

TurboModules can be written using Objective-C or C++. In order to support both cases, any source files that include C++ code should use the `.mm` file extension. This extension corresponds to Objective-C++, a language variant that allows for the use of a combination of C++ and Objective-C in source files.

> Use Xcode to rename existing files to ensure file references persist in your project. You might need to clean the build folder (_Project → Clean Build Folder_) before re-building the app. If the file is renamed outside of Xcode, you may need to click on the old `.m` file reference and Locate the new file.
:::info

Use Xcode to rename existing files to ensure file references persist in your project. You might need to clean the build folder (_Project → Clean Build Folder_) before re-building the app. If the file is renamed outside of Xcode, you may need to click on the old `.m` file reference and Locate the new file.

:::

## iOS: TurboModules: Ensure your App Provides an `RCTCxxBridgeDelegate`

Expand Down
6 changes: 5 additions & 1 deletion docs/new-architecture-app-modules-android.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,11 @@ Make sure your application meets all the [prerequisites](new-architecture-app-in

## 1. Enable NDK and the native build

> NOTE: In this iteration of the playbook we’re setting up the project to let you build from source. You might notice an increase in your build time because of this. We’re looking into what would be the preferred approach here so please feel free to share your feedbacks.
:::caution

In this iteration of the playbook we’re setting up the project to let you build from source. You might notice an increase in your build time because of this. We’re looking into what would be the preferred approach here so please feel free to share your feedbacks.

:::

The code-gen will output some Java and some C++ code that now we need to build.

Expand Down
37 changes: 19 additions & 18 deletions docs/new-architecture-app-modules-ios.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ Make sure your application meets all the [prerequisites](new-architecture-app-in
Add the following imports at the top of your bridge delegate (e.g. `AppDelegate.mm`):

```objc
#import<ReactCommon/RCTTurboModuleManager.h>
#import<React/CoreModulesPlugins.h>
#import <ReactCommon/RCTTurboModuleManager.h>
#import <React/CoreModulesPlugins.h>
```

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:
Expand All @@ -34,9 +34,7 @@ To conform to the `RCTTurboModuleManagerDelegate` protocol, you will implement t

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
// AppDelegate.mm

```objc title='AppDelegate.mm'
// ...

#import <React/RCTDataRequestHandler.h>
Expand All @@ -60,9 +58,9 @@ Take note of `getModuleInstanceFromClass:` in the following example, as it inclu
return RCTCoreModulesClassProvider(name);
}

- (std::shared_ptr<facebook::react::TurboModule>)getTurboModule:(const std::string &)name
jsInvoker:(std::shared_ptr<facebook::react::CallInvoker>)jsInvoker
{
- (std::shared_ptr<facebook::react::TurboModule>)
getTurboModule:(const std::string &)name
jsInvoker:(std::shared_ptr<facebook::react::CallInvoker>)jsInvoker {
return nullptr;
}

Expand All @@ -78,13 +76,15 @@ Take note of `getModuleInstanceFromClass:` in the following example, as it inclu
return @ [[RCTGIFImageDecoder new]];
}];
} else if (moduleClass == RCTNetworking.class) {
return [[moduleClass alloc] initWithHandlersProvider:^NSArray<id<RCTURLRequestHandler>> *(RCTModuleRegistry * moduleRegistry) {
return @[
[RCTHTTPRequestHandler new],
[RCTDataRequestHandler new],
[RCTFileRequestHandler new],
];
}];
return [[moduleClass alloc]
initWithHandlersProvider:^NSArray<id<RCTURLRequestHandler>> *(
RCTModuleRegistry *moduleRegistry) {
return @[
[RCTHTTPRequestHandler new],
[RCTDataRequestHandler new],
[RCTFileRequestHandler new],
];
}];
}
// No custom initializer here.
return [moduleClass new];
Expand All @@ -102,9 +102,10 @@ Next, you will create a `RCTTurboModuleManager` in your bridge delegate’s `jsE
{
// Add these lines to create a TurboModuleManager
if (RCTTurboModuleEnabled()) {
_turboModuleManager = [[RCTTurboModuleManager alloc] initWithBridge:bridge
delegate:self
jsInvoker:bridge.jsCallInvoker];
_turboModuleManager =
[[RCTTurboModuleManager alloc] initWithBridge:bridge
delegate:self
jsInvoker:bridge.jsCallInvoker];

// Necessary to allow NativeModules to lookup TurboModules
[bridge setRCTTurboModuleRegistry:_turboModuleManager];
Expand Down
134 changes: 71 additions & 63 deletions docs/new-architecture-app-renderer-android.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,50 +11,52 @@ In order to enable Fabric in your app, you would need to add a `JSIModulePackage

Once you located it, you need to add the `getJSIModulePackage` method as from the snippet below:

```java
```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<JSIModuleSpec> getJSIModules(
final ReactApplicationContext reactApplicationContext,
final JavaScriptContextHolder jsContext) {
final List<JSIModuleSpec> specs = new ArrayList<>();
specs.add(new JSIModuleSpec() {
@Override
public JSIModuleType getJSIModuleType() {
return JSIModuleType.UIManager;
}

@Override
public JSIModuleProvider<UIManager> 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;
}
};
}
private final ReactNativeHost mReactNativeHost =
new ReactNativeHost(this) {

// Add those lines:
@Nullable
@Override
protected JSIModulePackage getJSIModulePackage() {
return new JSIModulePackage() {
@Override
public List<JSIModuleSpec> getJSIModules(
final ReactApplicationContext reactApplicationContext,
final JavaScriptContextHolder jsContext) {
final List<JSIModuleSpec> specs = new ArrayList<>();
specs.add(new JSIModuleSpec() {
@Override
public JSIModuleType getJSIModuleType() {
return JSIModuleType.UIManager;
}

@Override
public JSIModuleProvider<UIManager> 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`
Expand Down Expand Up @@ -114,18 +116,20 @@ First, make sure you followed the instructions to [Enabling the New Renderer (Fa
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:

```javascript
```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<NativeProps>(
'RCTWebView',
): HostComponent<NativeProps>);
```

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).

```javascript title="RNTMyNativeViewNativeComponent.js"
```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';
Expand All @@ -134,9 +138,9 @@ import type {ViewProps} from 'react-native/Libraries/Components/View/ViewPropTyp
type NativeProps = $ReadOnly<{|
...ViewProps, // This is required.
someNumber: Int32,
|}>;
|}>;

...
[...]

export default (codegenNativeComponent<NativeProps>(
'RNTMyNativeView',
Expand All @@ -152,8 +156,8 @@ export default (codegenNativeComponent<NativeProps>(
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
/** View manager for MyNativeView components. */
```java title='MyNativeViewManager.java'
// View manager for MyNativeView components.
@ReactModule(name = MyNativeViewManager.REACT_CLASS)
public class MyNativeViewManager extends SimpleViewManager<MyNativeView>
implements RNTMyNativeViewManagerInterface<MyNativeView> {
Expand Down Expand Up @@ -222,6 +226,8 @@ public class MyApplication extends Application implements ReactApplication {
});
return packages;
}
};
}
```

3. **Add a Fabric Component Registry**
Expand All @@ -240,24 +246,24 @@ import com.facebook.soloader.SoLoader;

@DoNotStrip
public class MyComponentsRegistry {
static {
SoLoader.loadLibrary("fabricjni");
}
static {
SoLoader.loadLibrary("fabricjni");
}

@DoNotStrip private final HybridData mHybridData;
@DoNotStrip private final HybridData mHybridData;

@DoNotStrip
private native HybridData initHybrid(ComponentFactory componentFactory);
@DoNotStrip
private native HybridData initHybrid(ComponentFactory componentFactory);

@DoNotStrip
private MyComponentsRegistry(ComponentFactory componentFactory) {
mHybridData = initHybrid(componentFactory);
}
@DoNotStrip
private MyComponentsRegistry(ComponentFactory componentFactory) {
mHybridData = initHybrid(componentFactory);
}

@DoNotStrip
public static MyComponentsRegistry register(ComponentFactory componentFactory) {
return new MyComponentsRegistry(componentFactory);
}
@DoNotStrip
public static MyComponentsRegistry register(ComponentFactory componentFactory) {
return new MyComponentsRegistry(componentFactory);
}
}
```

Expand Down Expand Up @@ -287,7 +293,7 @@ public class MyApplication extends Application implements ReactApplication {
CoreComponentsRegistry.register(componentFactory);

// Add this line just below CoreComponentsRegistry.register
MyComponentsRegistry.register(componentFactory)
MyComponentsRegistry.register(componentFactory);

// ...
}
Expand All @@ -296,6 +302,8 @@ public class MyApplication extends Application implements ReactApplication {
}
};
}
};
}
```

### Native/C++ Changes
Expand Down
18 changes: 11 additions & 7 deletions docs/new-architecture-app-renderer-ios.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,30 +64,34 @@ The way to render your app with Fabric depends on your setup. Here is an example
#import <react/config/ReactNativeConfig.h>
#endif

@interface AppDelegate () <RCTCxxBridgeDelegate, RCTTurboModuleManagerDelegate> {
@interface AppDelegate () <RCTCxxBridgeDelegate,
RCTTurboModuleManagerDelegate> {
#ifdef RN_FABRIC_ENABLED
RCTSurfacePresenterBridgeAdapter *_bridgeAdapter;
std::shared_ptr<const facebook::react::ReactNativeConfig> _reactNativeConfig;
facebook::react::ContextContainer::Shared _contextContainer;
#endif

// Find a line that define rootView and replace/edit with the following lines.
// Find a line that define rootView and replace/edit with the following lines.

#ifdef RN_FABRIC_ENABLED
_contextContainer = std::make_shared<facebook::react::ContextContainer const>();
_reactNativeConfig = std::make_shared<facebook::react::EmptyReactNativeConfig const>();

_contextContainer->insert("ReactNativeConfig", _reactNativeConfig);

_bridgeAdapter = [[RCTSurfacePresenterBridgeAdapter alloc] initWithBridge:_bridge contextContainer:_contextContainer];
_bridgeAdapter = [[RCTSurfacePresenterBridgeAdapter alloc]
initWithBridge:_bridge
contextContainer:_contextContainer];

_bridge.surfacePresenter = _bridgeAdapter.surfacePresenter;

UIView *rootView = [[RCTFabricSurfaceHostingProxyRootView alloc] initWithBridge:_bridge
moduleName:@"MyTestApp"
initialProperties:nil];
UIView *rootView =
[[RCTFabricSurfaceHostingProxyRootView alloc] initWithBridge:_bridge
moduleName:@"MyTestApp"
initialProperties:nil];
#else
// Current implementation to define rootview.
// Current implementation to define rootview.
RCTRootView *rootView = [[RCTRootView alloc] initWithBridge:bridge
moduleName:@"MyTestApp"
initialProperties:nil];
Expand Down
2 changes: 1 addition & 1 deletion docs/new-architecture-appendix.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ You can trigger the code-gen by invoking the following task:

The extra `--rerun-tasks` flag is added to make sure Gradle is ignoring the `UP-TO-DATE` checks for this task. You should not need it during normal development.

The `generateCodegenArtifactsFromSchema` task normally runs before the `preBuild` task, so you should not need to invoke it manually but it will be triggered before your builds.
The `generateCodegenArtifactsFromSchema` task normally runs before the `preBuild` task, so you should not need to invoke it manually, but it will be triggered before your builds.

### Invoking the script manually

Expand Down
6 changes: 5 additions & 1 deletion docs/new-architecture-library-android.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,11 @@ react {
}
```

_(Please note that this setup requires you to have the React Gradle Plugin configured in the prerequisite step)._
:::info

Please note that this setup requires you to have the React Gradle Plugin configured in the prerequisite step).

:::

There are three arguments that are required:

Expand Down
Loading