

Simple, performant & type-safe cross platform navigation in React Native
source link: https://reactnativeexample.com/simple-performant-type-safe-cross-platform-navigation-in-react-native/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

react-native-ridge-navigation
Simple and performant cross platform navigation on iOS, Android and the web with simple and type-safe api for React 18 (alpha)
⚠️ This is beta software, things can break.
Things which are not finished yet:
- useFocus (like useEffect but for when screen is focused)
- documentation
- create universal lazyWithPreload for screens (only on web, but callstack/repack can fix it native too)
- universal modal (web support too)
Features
- Superior performance (we use wix/react-native-navigation)
- Simple api
- Type safety
- Type safe routes
- Type safe params (based on url)
- Android, iOS & web!
- Preload data on mouseDown (or more sensitive on hover, see
<Link />
example) - Preload component on hover (on web)
- Automatic deep-linking
- Lazy load components
- Real-time light/dark mode
Example
View video in better frame on YouTube
About us
We want developers to be able to build software faster using modern tools like GraphQL, Golang and React Native.
Give us a follow on Twitter:
RichardLindhout,
web_ridge
Donate
Please contribute or donate so we can spend more time on this library
See example: reactnativeridgenavigation.com
Source
Register screens
You can register screens with a preload function, the params will be automatically in string format based on the url.
// NavigatorRoutes.ts
const PostScreen = registerScreen(
'/post/:id',
PostScreenLazy,
({ id }) => {
queryClient.prefetchQuery(
queryKeyPostScreen({ id }),
queryKeyPostScreenPromise({ id })
);
// if you return something here it can be used in the screen itself or somewhere else with
// usePreloadResult(routes.PostScreen)
// in this case react-query handles it based on queryKey so it's not needed but with Relay.dev it is.
// you can put the result of the usePreloadResult in your usePreloadedQuery if you use Relay.dev
}
);
const routes = {
PostScreen,
// ...
}
export default routes
Supported stacks
- normal
- bottomTabs
- sideMenu (in progress)
Installation
1. If you don't have an app yet (optional, but recommended)
Create the app with our tool web-ridge/create-react-native-web-application
npx create-react-native-web-application --name myappname
1. Install deps + library
yarn add react-native-navigation react-native-navigation-hooks react-native-ridge-navigation history && npx rnn-link && npx pod-install
or with npm
npm install react-native-navigation react-native-navigation-hooks react-native-ridge-navigation history && npx rnn-link && npx pod-install
2. Extra (optional)
Add react-native-web-image-loader (see example), this will make sure the images in the BottomBar will be in good quality on the web.
const {
addWebpackModuleRule,
} = require('customize-cra');
// ...
addWebpackModuleRule({
test: /\.(png|jpe?g|gif)$/,
options: {
name: 'static/media/[name].[hash:8].[ext]',
scalings: { '@3x': 1 },
},
loader: 'react-native-web-image-loader',
})
// ...
Usage
import {
createNormalRoot,
createNavigation,
createBottomTabsRoot,
createScreens,
defaultTheme,
} from 'react-native-ridge-navigation';
export const NavigationRoots = {
RootHome: 'home',
RootAuth: 'auth',
};
// svg to png
// https://webkul.github.io/myscale/
//
// tab icon
// http://nsimage.brosteins.com/Home
export const BottomRoots = {
Posts: {
path: '/post',
title: () => 'Posts',
icon: require('./img/palette-swatch-outline/icon-20.png'),
selectedIcon: require('./img/palette-swatch/icon-20.png'),
child: routes.PostsScreen,
},
Account: {
path: '/account',
title: () => 'Account',
icon: require('./img/account-circle-outline/icon-20.png'),
selectedIcon: require('./img/account-circle/icon-20.png'),
child: routes.AccountScreen,
},
};
const Navigator = createNavigation(
defaultTheme,
createScreens(routes),
{
[NavigationRoots.RootHome]: createBottomTabsRoot(
[BottomRoots.Posts, BottomRoots.Account],
// optional settings
// {
// breakingPointWidth: 500, // default is 1200
// components: {
// start: BottomTabStart,
// end: BottomTabEnd,
// },
// }
),
[NavigationRoots.RootAuth]: createNormalRoot(routes.AuthScreen),
// You can add endless more roots for your app e.g. for different roles of users
// ...
},
AppHOC
);
export default Navigator;
New screen
Use the <Link />
component as much as possible since it will work with ctrl+click on the web :)
<Link
to={routes.PostScreen}
params={{ id: `${item.id}` }}
// mode="default" // optional if sensitive the preload will be called on hover instead of mouseDown
>
{(linkProps) => (
<Pressable {...linkProps}> // or other touchables/buttons
<Text>go to post</Text>
</Pressable>
)}
</Link>
Alternative push (or replace)
const { push, replace } = useNavigation();
// call this where if you can't use <Link />
push(routes.PostScreen, {
id: `${item.id}`
});
// call this if e.g. after a create you want to go to edit screen
// but without pushing history to the url-stack or app-stack :)
replace(routes.PostScreen, {
id: `${item.id}`
});
Switch root
Switch root can be used to switch from e.g. the auth screen to a different entrypoint of your app. E.g. check the role and switch the stacks to different roots for different user roles.
<SwitchRoot rootKey={NavigationRoots.RootHome} params={{}} />;
// or e.g.
<SwitchRoot rootKey={NavigationRoots.RootAuth} params={{}} />;
useNavigation
All available properties
const {
refreshBottomTabs, // e.g. after language change and you want to update labels
updateBadge, // updateBadge(BottomRoots.Projects, '10');
pop, // go back
switchBottomTabIndex, // switch bottom tab
switchRoot,
preload, // call preload (done automatic on link mouseDown
push, // calls preload + pushes screen
replace, // calls preload + pushes screen
} = useNavigation()
Deep linking
You have to enable url schemes etc in your app and it'll work!
// global
DeepLinking // see deep linking documentation
OnlyRenderOnce // see deep linking documentation
SwitchRoot
Link
BackLink // for now .pop() but we'll update this according to Android guidelines later on (to always go back in hierarchy)
lazyWithPreload // only available on the web: see example app
Redirect
NavigationRoot,
createNavigation,
refreshBottomTabs,
updateBadge,
createBottomTabsRoot,
createNormalRoot,
createSideMenuRoot,
registerScreen,
createScreens,
defaultTheme,
setTheme,
getTheme,
createSimpleTheme,
setPreloadResult, // should not need this as it is done automatically
// hooks
useTheme,
useParams,
useNavigation,
useFocus
usePreloadResult // e.g. usePreloadResult(routes.PostScreen)
GitHub
Recommend
-
31
Tabs A cross-platform Collapsible Tab View component for React Native Dec 03, 2020...
-
20
@benjeau/react-native-draw Cross-platform React Native drawing component based on SVG. Example applic...
-
8
Tabs Smooth and fast cross platform Material Design Tabs for React Native Paper Dec...
-
7
React Native Hold Menu A performant, easy to use hold to open context menu for React Native powered by Reanimated. Features Powered with Reanimated v2. 🚀 Smooth interactions & animations. Su...
-
47
Search A cross-platform selector/picker component for React Native May 07, 2021...
-
12
react-native-fast-toast Toast component for React Native, supports Android, IOS and Web Features Fully Customizable Swipe to close support Smooth animation Fully typed with TypeScr...
-
9
React Native Awesome Gallery Photos gallery powered by Reanimated v2 and react-native-gesture-handler
-
8
-
11
React Native Animated Bottom Drawer A lightweight and highly performant bottom drawer for react native Features Extremely lightweight (~15kb) and highly performant Support for snapping (multi level bottom dr...
-
10
React Native Timer Picker ⏰🕰️⏳ A simple, flexible, performant duration picker component for React Native apps 🔥 Great for timers, alarms and duration inputs ⏰🕰️⏳ Works with Expo and bare React Native apps. Demos 📱
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK