I recently started building mobile app using React Native and started liking on how fast I can build the mobile app. There were few issues I’ve ran into while setting up which I’ll share here and show you how we can setup the drawer navigation.
I’m using Node v11.0.0, however this has been tested in Node v8.x.
React Native CLI v2.0.1 (Run npm i -g react-native-cli
).
Setup a project by running react-native init DrawerNavigationDemo
Change the directory to cd DrawerNavigationDemo
Install the React Navigation package:
npm i -S react-navigation
npm i -S react-native-gesture-handler
Then link the packages by running react-native link
I installed
react-navigation
andreact-native-gesture-handler
packages at one shot (npm i -S react-navigation react-native-gesture-handler
), even though the document shows it as a two step. And then I ranreact-native link
. This caused an issue, I was gettingUndefined object
error atGesture Handler
. I’m not pretty sure on why this happens. I’ve solved this by installingreact-navigation
first and then thereact-native-gesture-handler
next.
All the folders and files are generated by react-native init
command that we have run earlier, except screens
and components
folder.
Let’s add our first screen and we call it as HomeScreen
. Create HomeScreen.js
under screens/
directory and add the following code:
import React from 'react'
import { View, Text } from 'react-native'
const HomeScreen = () => {
return (
<View>
<Text>This is Home Screen</Text>
</View>
)
}
export default HomeScreen
The above code just adds a text field in the mobile view, nothing much fancy here.
Create another screen called SettingsScreen.js
under screens/
directory with the following code:
import React from 'react'
import { View, Text } from 'react-native'
const SettingsScreen = () => {
return (
<View>
<Text>This is Settings Screen</Text>
</View>
)
}
export default SettingsScreen
Now we have screens, let’s add drawer navigation to navigate to these screens. To do that, we have to replace the code of App.js
with the following:
import { createDrawerNavigator, createAppContainer } from 'react-navigation'
import HomeScreen from './screens/HomeScreen'
import SettingsScreen from './screens/SettingsScreen'
const AppNavigator = createDrawerNavigator({
Home: {
screen: HomeScreen
},
Settings: {
screen: SettingsScreen
}
})
export default createAppContainer(AppNavigator)
We create the drawer navigation using the method createDrawerNavigator
from react-navigation
and configure with list of screens. Here we have two screens Home
and Settings
.
Then we export the app with createAppContainer
higher-order function from react-navigation
. This is required to access the navigation props in our screen components.
We’ve everything to run our app now. Let’s run it by using: react-native run-ios
You should be able to pull the drawer from the left side of the simulator.
Wow! Under 5 minutes we’ve added the drawer navigation.
Let’s style it up by adding header with Hamburger menu.
We use React Native Elements to add few styled native elements to our app. To add, please run npm i -S react-native-elements
and then run npm i -S react-native-vector-icons
as this is a peer dependency by react-native-elements
.
We’ll have to link the packages again, run react-native link
.
Create a MyHeader.js
file under components\
directory and add the following code:
import React from 'react'
import { Header } from 'react-native-elements'
import HamburgerMenu from './HamburgerMenu'
const MyHeader = props => {
return (
<Header
leftComponent={<HamburgerMenu navigation={props.navigation} />}
centerComponent={{
text: props.title,
style: { color: '#fff', fontWeight: 'bold' }
}}
statusBarProps={{ barStyle: 'light-content' }}
/>
)
}
export default MyHeader
Here, we’re using Header
component from react-native-elements
package and configuring with leftComponent
and centerComponent
. The left component is the HamburgerMenu
and the center component is the title of the screen.
Let’s create HamburgerMenu.js
under components\
directory:
import React from 'react'
import { Icon } from 'react-native-elements'
const HamburgerMenu = props => {
return (
<Icon
color="#fff"
name="menu"
onPress={() => props.navigation.toggleDrawer()}
/>
)
}
export default HamburgerMenu
We added the icon with 3 dashes which is called as Hamburger menu and while pressing the icon, we toggle the drawer navigation.
Now we’ve our own header with custom hamburger menu. Let’s tie up everything.
Open up HomeScreen.js
and edit as follows:
import React from 'react'
import { View, Text } from 'react-native'
import MyHeader from '../components/MyHeader'
const HomeScreen = props => {
return (
<View>
<MyHeader navigation={props.navigation} title="Home" />
<Text>This is Home Screen</Text>
</View>
)
}
export default HomeScreen
We’ve added MyHeader
component and passing navigation
props which we receive from react-navigation
package via higher-order component which we’ve seen earlier.
Repeat the same for SettingsScreen.js
:
import React from 'react'
import { View, Text } from 'react-native'
import MyHeader from '../components/MyHeader'
const SettingsScreen = props => {
return (
<View>
<MyHeader navigation={props.navigation} title="Settings" />
<Text>This is Settings Screen</Text>
</View>
)
}
export default SettingsScreen
Let’s reload our app and see how it looks:
Great! That looks pretty!
First thing is that, as per react-navigation
document, you’ll have to modify ./android/app/src/main/java/com/drawernavigationdemo/MainActivity.java
file. Refer React Navigation doc.
After running react-native run-android
, I got into some issues related to the bundler. I’ve fixed it by googling around and found the following steps from somewhere:
./android/gradlew clean
react-native bundle --platform android --dev false --entry-file index.js --bundle-output android/app/src/main/assets/index.android.bundle --assets-dest android/app/src/main/res
Wait for some time till the bundler finishes its job. Then run react-native run-android
and all will run smoothly.
Make sure your emulator is already running.
Hope this post is useful. If yes, please hit like and share it.