Use the DefaultImplementation
masterDefaultImplementation which is used by default if no other implementation is specified. You can find details about its behavior in the DefaultImplementation documentation.repository·master·Indexed 25 days ago
https://github.com/airbnb/native-navigationA navigation library for React Native built on top of actual iOS and Android platform navigational components. It provides a core Navigator instance with methods like registerScreen, push, present, pop, and dismiss, along with components for configuration (Navigator.Config), tab bars (TabBar, Tab), and shared element transitions (SharedElement, SharedElementGroup).
DefaultImplementation which is used by default if no other implementation is specified. You can find details about its behavior in the DefaultImplementation documentation.The native-navigation project provides several guides to help you implement and customize navigation in your mobile applications. Available guides include:
Native Navigation uses a 'Screen' based architecture where each screen is a top-level React component registered individually. This allows for better code splitting and performance by preventing all code from executing at app start.
A recommended directory structure separates components from screens and uses a central routes.js file for screen identifiers (similar to URLs) and an index.js file as the entry point for the JavaScript bundle.
Recommended structure:
root/
├── components/
├── screens/
│ ├── FooScreen.js
│ └── BarScreen.js
├── routes.js
└── index.js// routes.js
export const FOO = 'MyApp/Foo';
export const BAR = 'MyApp/Bar';
// index.js
import Navigator from 'native-navigation';
import { FOO, BAR } from './routes';
Navigator.registerScreen(FOO, () => require('./screens/FooScreen'));
Navigator.registerScreen(BAR, () => require('./screens/BarScreen'));To use a custom navigation solution on iOS, implement the ReactNavigationImplementation protocol. This protocol allows you to control how navigation controllers are created and how screen, tab, and tab bar configurations are reconciled with the native UI.
Once implemented, inject your custom implementation into the ReactNavigationCoordinator singleton.
// 1. Implement the protocol
protocol ReactNavigationImplementation {
func makeNavigationController(rootViewController: UIViewController) -> UINavigationController
func reconcileScreenConfig(
viewController: ReactViewController,
navigationController: UINavigationController?,
prev: [String: AnyObject],
next: [String: AnyObject]
)
func reconcileTabConfig(
tabBarItem: UITabBarItem,
prev: [String: AnyObject],
next: [String: AnyObject]
)
func reconcileTabBarConfig(
tabBar: UITabBar,
prev: [String: AnyObject],
next: [String: AnyObject]
)
func getBarHeight(
viewController: ReactViewController,
navigationController: UINavigationController?,
config: [String: AnyObject]
) -> CGFloat
}
// 2. Inject the implementation
let implementation: ReactNavigationImplementation = MyCustomNavigationImplementation();
ReactNavigationCoordinator.sharedInstance.navigation = implementation;To use a custom navigation solution on Android, implement the NavigationImplementation interface. This interface provides hooks for reconciling navigation properties, preparing option menus, handling menu item selections, calculating bar heights, and managing tab items and tab bar properties.
Once implemented, inject your custom implementation into the ReactNavigationCoordinator singleton using injectImplementation.
// 1. Implement the interface
interface NavigationImplementation {
void reconcileNavigationProperties(
ReactInterface component,
ReactToolbar toolbar,
ActionBar bar,
ReadableMap previous,
ReadableMap next,
boolean firstCall
);
void prepareOptionsMenu(
ReactInterface component,
ReactToolbar toolbar,
ActionBar bar,
Menu menu,
ReadableMap previous,
ReadableMap next
);
boolean onOptionsItemSelected(
ReactInterface component,
ReactToolbar toolbar,
ActionBar bar,
MenuItem item,
ReadableMap config
);
float getBarHeight(
ReactInterface component,
ReactToolbar toolbar,
ActionBar actionBar,
ReadableMap config,
boolean firstCall
);
void makeTabItem(
ReactBottomNavigation bottomNavigation,
Menu menu,
int index,
Integer itemId,
ReadableMap config
);
void reconcileTabBarProperties(
ReactBottomNavigation bottomNavigation,
Menu menu,
ReadableMap prev,
ReadableMap next
);
}
// 2. Inject the implementation
NavigationImplementation implementation = new MyCustomNavigationImplementation();
ReactNavigationCoordinator.sharedInstance.injectImplementation(implementation);Because Native Navigation registers each screen as a separate root view, you can reduce Redux boilerplate by creating a custom registration wrapper. Instead of calling Navigator.registerScreen directly, you can implement a wrapper that injects the Redux Provider into every screen automatically.
To implement this, create a helper function that takes a getStore option. This function should return a component that wraps the target screen with the <Provider store={store}> component.
// index.js
import registerConnectedScreen from './utils/registerConnectedScreen';
registerConnectedScreen(
'SomeScreen',
() => require('./screens/SomeScreen'),
{
getStore: () => require('./path/to/redux/store'),
},
);When switching to CocoaPods, you must remove the statically linked libraries provided by the React Native starter template to avoid conflicts:
.xcworkspace file in Xcode.Libraries folder.To start a new project, use the React Native CLI. If you do not have the CLI installed, install it globally first. Then, initialize your project and install native-navigation via npm.
IMPORTANT: Do NOT use react-native link to link native-navigation; it is currently not supported.
npm i -g react-native-cli
react-native init MyNewProject
cd MyNewProject
npm i --save native-navigationTo use the native-navigation library, import the default Navigator export from the native-navigation package.
import Navigator from 'native-navigation';To integrate Native Navigation into your Android application lifecycle, perform the following steps in MainApplication.java:
NativeNavigationPackage to the getPackages() list.onCreate() method, initialize the ReactNavigationCoordinator with your ReactInstanceManager and call .start(this).import com.airbnb.android.react.navigation.NativeNavigationPackage;
import com.airbnb.android.react.navigation.ReactNavigationCoordinator;
// ... inside MainApplication class
@Override
protected List<ReactPackage> getPackages() {
return Arrays.<ReactPackage>asList(
new MainReactPackage(),
new NativeNavigationPackage()
);
}
@Override
public void onCreate() {
super.onCreate();
SoLoader.init(this, /* native exopackage */ false);
// Initialize Native Navigation
ReactNavigationCoordinator coordinator = ReactNavigationCoordinator.sharedInstance;
coordinator.injectReactInstanceManager(mReactNativeHost.getReactInstanceManager());
coordinator.start(this);
}import com.airbnb.android.react.navigation.NativeNavigationPackage;
import com.airbnb.android.react.navigation.ReactNavigationCoordinator;
@Override
protected List<ReactPackage> getPackages() {
return Arrays.<ReactPackage>asList(
new MainReactPackage(),
new NativeNavigationPackage()
);
}
@Override
public void onCreate() {
super.onCreate();
SoLoader.init(this, /* native exopackage */ false);
ReactNavigationCoordinator coordinator = ReactNavigationCoordinator.sharedInstance;
coordinator.injectReactInstanceManager(mReactNativeHost.getReactInstanceManager());
coordinator.start(this);
}