Hey folks,
In this article we will be creating App Shortcuts for React Native apps as shown in the image. We will be creating this using the react-native-app-shortcuts library.
First things first !!
node --version
v16.14.1
npm --version
8.5.0
java --version
openjdk 11.0.11 2021-04-20
Create a New React Native App using the following commands -
npx react-native init [YOUR_PROJECT_NAME] --version 0.68.2
Note - I am using 0.68 version of React Native. If you have upgraded React Native to the latest version you can create the app using the command ->
npx react-native init [YOUR_PROJECT_NAME]
Let's install the dependencies
We will be installing navigation dependencies to support navigation between multiple screens in our app.
npm install @react-navigation/native @react-navigation/native-stack
npm install react-native-screens react-native-safe-area-context
After the navigation dependencies we will be installing react-native-app-shortcuts library in our app.
npm i react-native-app-shortcuts
Final package.json
file should be similar to this ->
package.json
{
"name": "RNAppShortcuts",
"version": "0.0.1",
"private": true,
"scripts": {
"android": "react-native run-android",
"ios": "react-native run-ios",
"start": "react-native start",
"test": "jest",
"lint": "eslint ."
},
"dependencies": {
"@react-navigation/native": "^6.0.11",
"@react-navigation/native-stack": "^6.7.0",
"react": "17.0.2",
"react-native": "0.68.2",
"react-native-app-shortcuts": "^0.2.0",
"react-native-safe-area-context": "^4.3.1",
"react-native-screens": "^3.15.0"
},
"devDependencies": {
"@babel/core": "^7.18.10",
"@babel/runtime": "^7.18.9",
"@react-native-community/eslint-config": "^3.1.0",
"babel-jest": "^28.1.3",
"eslint": "^8.21.0",
"jest": "^28.1.3",
"metro-react-native-babel-preset": "^0.72.0",
"react-test-renderer": "17.0.2"
},
"jest": {
"preset": "react-native"
}
}
Let's begin the journey of Code ->
- Remove the template code in
App.js
and ensureApp.js
looks like the following -
App.js
import React from 'react';
import {
StyleSheet,
Text,
View,
} from 'react-native';
const App = () => {
return (
<View>
</View>
);
};
const styles = StyleSheet.create({
});
export default App;
Remove the
styles
constant and imports from 'react-native'We will create a Navigation Container and a Stack Navigator that contains different screens for our app.
Import NavigationContainer and createNativeStackNavigator() from 'react-navigation/native' and 'react-navigation/native-stack' respectively.
import {NavigationContainer} from '@react-navigation/native';
import {createNativeStackNavigator} from '@react-navigation/native-stack';
- Modify the return statement of
App.js
file. Return aNavigationContainer
that encloses ourStack.Navigator
inside which all our screens are defined along with their names and components.
return (
<NavigationContainer>
<Stack.Navigator>
<Stack.Screen name="Home" component={HomeComponent} />
<Stack.Screen name="Notification" component={NotificationComponent} />
<Stack.Screen name="Chat" component={ChatComponent} />
</Stack.Navigator>
</NavigationContainer>
);
- Next we will be defining these components namely -
HomeComponent
,NotificationComponent
andChatComponent
.
In the same App.js
file create three constants like ->
const NotificationComponent = ({navigation}) => {
return (
<>
<Notification navigation={navigation} />
</>
);
};
const ChatComponent = ({navigation}) => {
return (
<>
<Chat navigation={navigation} />
</>
);
};
const HomeComponent = ({navigation}) => {
return (
<>
<Home navigation={navigation} />
</>
);
};
- Import the Chat, Home, Notification screens like ->
import Notification from './src/Notification';
import Chat from './src/Chat';
import Home from './src/Home';
At this stage your App.js
would look like the following ->
App.js
import React from 'react';
import {NavigationContainer} from '@react-navigation/native';
import {createNativeStackNavigator} from '@react-navigation/native-stack';
import Notification from './src/Notification';
import Chat from './src/Chat';
import Home from './src/Home';
const Stack = createNativeStackNavigator();
const NotificationComponent = ({navigation}) => {
return (
<>
<Notification navigation={navigation} />
</>
);
};
const ChatComponent = ({navigation}) => {
return (
<>
<Chat navigation={navigation} />
</>
);
};
const HomeComponent = ({navigation}) => {
return (
<>
<Home navigation={navigation} />
</>
);
};
const App = () => {
return (
<NavigationContainer>
<Stack.Navigator>
<Stack.Screen name="Home" component={HomeComponent} />
<Stack.Screen name="Notification" component={NotificationComponent} />
<Stack.Screen name="Chat" component={ChatComponent} />
</Stack.Navigator>
</NavigationContainer>
);
};
export default App;
At this stage it might be showing you errors that Home, Notification and Chat screens does not exists and hence they cannot be imported.
Let's fix this next.
Create a folder src at the level where
App.js
file is located.Create 3 files inside the src folder namely -> Home.js, Notification.js and Chat.js
Also for icons download Notification icon and Chat icon from the respective links as .png images and add in the app project structure at the location
android/app/src/main/res/drawable
- Your folder structure for adding png files of Icons will be ->
- Your folder structure should finally look like this ->
Steps for creating screens Home.js, Chat.js and Notification.js
Home.js
Create a functional component named Home.js and export it as default from this file.
Make Sure each of the Screen Home.js, Chat.js and Notification.js acceptsnotification
object asprops
const Home = ({navigation}) => {
return (
);
};
export default Home;
Create a styles constant and create homeStyle.
const styles = StyleSheet.create({
homeStyle: {
display: 'flex',
flex: 1,
justifyContent: 'center',
alignSelf: 'center',
},
});
homeStyle will be assigned to the single view in the Home Screen with the flex value as 1 so that it takes the entire space.
justifyContent
andalignSelf
styles are used to align the Text component inside the View in the centre of the screen.Inside the return method of Home functional component return View with styles as homeStyle which contains a Text Component as "Home Screen"
return (
<View style={styles.homeStyle}>
<Text>{'Home Screen'}</Text>
</View>
);
Home.js
at this stage will look like ->
Home.js
import React from 'react';
import {Text, StyleSheet, View} from 'react-native';
const Home = ({navigation}) => {
return (
<View style={styles.homeStyle}>
<Text>{'Home Screen'}</Text>
</View>
);
};
const styles = StyleSheet.create({
homeStyle: {
display: 'flex',
flex: 1,
justifyContent: 'center',
alignSelf: 'center',
},
});
export default Home;
Chat.js
Similarly create a screen Chat.js with the following code ->
Chat.js
import React from 'react';
import {StyleSheet, Text, TouchableOpacity} from 'react-native';
const Chat = ({navigation}) => {
return (
<TouchableOpacity
onPress={() => {
navigation.navigate('Notification');
}}
style={styles.cta1Style}>
<Text style={styles.ctaTitleStyle}>{'Switch to Notifications'}</Text>
</TouchableOpacity>
);
};
const styles = StyleSheet.create({
cta1Style: {
backgroundColor: 'red',
padding: 20,
},
ctaTitleStyle: {
color: 'white',
},
});
export default Chat;
Notification.js
Similarly create a screen Notification.js with the following code ->
import React from 'react';
import {StyleSheet, Text, TouchableOpacity} from 'react-native';
const Notification = ({navigation}) => {
return (
<TouchableOpacity
onPress={() => {
navigation.navigate('Chat');
}}
style={styles.cta2Style}>
<Text style={styles.ctaTitleStyle}>{'Switch to Chat'}</Text>
</TouchableOpacity>
);
};
const styles = StyleSheet.create({
cta2Style: {
backgroundColor: 'blue',
padding: 20,
},
ctaTitleStyle: {
color: 'white',
},
});
export default Notification;
And that's done... Now you might not be seeing any error if everything works perfectly...
Let's create the App Shortcuts for our app ->
Import
RNAppShortcuts
from 'react-native-app-shortcuts' inApp.js
fileInside the App functional component before the return statement create 2 actions using RNAppShortcuts.addShortcut({})
App.js
import React from 'react';
import {NavigationContainer} from '@react-navigation/native';
import {createNativeStackNavigator} from '@react-navigation/native-stack';
import Notification from './src/Notification';
import Chat from './src/Chat';
import Home from './src/Home';
import RNAppShortcuts from 'react-native-app-shortcuts';
const Stack = createNativeStackNavigator();
const NotificationComponent = ({navigation}) => {
return (
<>
<Notification navigation={navigation} />
</>
);
};
const ChatComponent = ({navigation}) => {
return (
<>
<Chat navigation={navigation} />
</>
);
};
const HomeComponent = ({navigation}) => {
return (
<>
<Home navigation={navigation} />
</>
);
};
const App = () => {
RNAppShortcuts.addShortcut({
id: '1',
shortLabel: 'Notify',
longLabel: 'Open Notifications',
iconFolderName: 'drawable',
iconName: 'notification',
});
RNAppShortcuts.addShortcut({
id: '2',
shortLabel: 'Chat',
longLabel: 'Open Chats',
iconFolderName: 'drawable',
iconName: 'chat',
});
return (
<NavigationContainer>
<Stack.Navigator>
<Stack.Screen name="Home" component={HomeComponent} />
<Stack.Screen name="Notification" component={NotificationComponent} />
<Stack.Screen name="Chat" component={ChatComponent} />
</Stack.Navigator>
</NavigationContainer>
);
};
export default App;
Now we will create handlers which will activate when one of the app shortcut is clicked.
In
Home.js
file import useEffect from React and create a useEffect() equivalent for ComponentWillMount() of class component for Home functional component.Also import RNAppShortcuts from 'react-native-app-shortcuts' for defining app shortcuts handler.
This useEffect will be triggered every time this screen loads or mounts. Here we will define our App Shortcuts handler.
App Shortcuts handler is created using
RNAppShortcuts.handleShortcut(id => {});
At this stage
Home.js
should look like ->
Home.js
import React, {useEffect} from 'react';
import {Text, StyleSheet, View} from 'react-native';
import RNAppShortcuts from 'react-native-app-shortcuts';
const Home = ({navigation}) => {
useEffect(() => {
RNAppShortcuts.handleShortcut(id => {
console.log(id);
if (id === '1') {
navigation.navigate('Notification');
} else if (id === '2') {
navigation.navigate('Chat');
}
});
}, []);
return (
<View style={styles.homeStyle}>
<Text>{'Home Screen'}</Text>
</View>
);
};
const styles = StyleSheet.create({
homeStyle: {
display: 'flex',
flex: 1,
justifyContent: 'center',
alignSelf: 'center',
},
});
export default Home;
Important Things to Note -
- They are multiple libraries in React Native for creating App Shortcuts.
- Shortcuts are added using the following code which accepts parameters like id, shortLabel , longLabel, iconFolderName where the icon image is located, iconName which has some naming rules.
RNAppShortcuts.addShortcut({
id,
shortLabel,
longLabel,
iconFolderName,
iconName,
});
Icon Images should be added in native android and iOS folders at right locations.
We can add all shortcuts to the app in Splash Screen or we can add app shortcuts based on which part of the app, user has explored.
We can remove app shortcuts using
RNAppShortcuts.removeShortCut(id)
We can remove all app shortcuts using
RNAppShortcuts.removeAllShortCuts()
Static app shortcuts are shortcuts that are created at the app installation time.
react-native-quick-actions library support static app shortcuts for IOS devices.
App shortcuts handler can be created using
RNAppShortcuts.handleShortcut(id => {});
The handler accepts id, using which we can perform different operations on different app shortcut click.
Voohooooooo!! We have complete the project. Cheers !!
Follow me on Twitter for more tech content on ReactNative and Flutter.
Top comments (0)