Skip to main content

Using Portals in React Native

Once you install Ionic Portals, you can start creating Portals for your application.

Creating a Portal and Rendering It​

Create a PortalView in your view hierarchy:

import { PortalView } from '@ionic/portals-react-native';

const helloPortal = {
// A unique name to reference later
name: 'hello',
// This is the location of your web bundle relative to the asset directory in Android and Bundle.main in iOS
// This will default to the name of the portal
startDir: 'portals/hello',
// Any initial state to be provided to a Portal if needed
initialContext: {
greeting: 'Hello, world!',
},
};

<PortalView
portal={helloPortal}
// Setting a size is required
style={{ flex: 1, height: 300 }}
/>;

iOS Specific Configuration​

AppDelegate​

Both Capacitor and React Native have classes named AppDelegate. To prevent a clash that can prevent your React Native application from launching, you will need to rename AppDelegate to something else:

// AppDelegate.h
@interface RNAppDelegate : UIResponder <UIApplicationDelegate, RCTBridgeDelegate>
// AppDelegate.m
@implementation RNAppDelegate
@end
// main.m
#import <UIKit/UIKit.h>

#import "AppDelegate.h"

int main(int argc, char *argv[])
{
@autoreleasepool {
return UIApplicationMain(argc, argv, nil, NSStringFromClass([RNAppDelegate class]));
}
}

Podfile​

There are two methods you may use to ensure Portals can integrate into your React Native application: a custom pre_install hook or adding use_frameworks! to your Podfile. Only one of these approaches is needed to ensure that Capacitor is compiled as a dynamic framework.

pre_install​

Using the pre_install hook allows you to keep all the other React Native dependencies as static frameworks:

# These frameworks are required to be dynamic.
dynamic_frameworks = ['Capacitor', 'CapacitorCordova']

pre_install do |installer|
installer.pod_targets.each do |pod|
if dynamic_frameworks.include?(pod.name)
def pod.static_framework?
false
end
def pod.build_type
Pod::BuildType.dynamic_framework
end
end
end
end

use_frameworks​

Alternative to the pre_install hook, you can add use_frameworks! to your Podfile application target. This forces all dependencies to be dynamic frameworks. Using this approach requires removing use_flipper!() from the Podfile.

Communicating between React Native and Web​

One of the key features of Ionic Portals for React Native is facilitating communication between the web and React Native layers of your application. Publishing a message to the web:

import { publish } from '@ionic/portals-react-native';

publish('topic', { number: 1 });

Subscribe to messages from the web:

import { subscribe } from '@ionic/portals-react-native';

// The subscribe function returns an EmitterSubscription that can be used to unsubscribe from events
let emitterSubscription = subscribe('topic', (message) => {
// Here you have access to:
// message.data - Any data sent from the web
// message.topic - The topic the message was published on
});

// To unsubscribe
emitterSubscription.remove();

To see an example of Portals Pub/Sub in action that manages the lifecycle of a subscription with the lifecycle of a React Native component, refer to the PubSubLabel implementation in the example project of the @ionic/portals-react-native source repo.

Using Capacitor Plugins​

If you need to use any Capacitor plugins, the classpath of the Android plugins and the Objective-C class name will have to be provided to the Portal plugins property.

const helloPortal = {
name: 'hello',
startDir: 'portals/hello',
plugins: [
{
androidClassPath: 'com.capacitorjs.plugins.camera.CameraPlugin',
iosClassName: 'CAPCameraPlugin',
},
],
initialContext: {
greeting: 'Hello, world!',
},
};

Bundling Your Web Apps​

Currently there is no tooling for bundling your web apps directly as part of @ionic/portals-react-native. Please follow the native guides to manage this as part of the native build process.