• TokenSoft

Creating a custom dropdown header component with React Navigation

by Aaron Biser

At TokenSoft, we build mobile applications with React Native and Expo as it allows for our developers to work with JavaScript while simultaneously building for iOS and Android. 

We also use React Navigation because it is powerful, simple to use and provides platform specific styling for iOS and Android. While being a very simple product to get up and running in any project, it is also easily customizable for anybody who is used to writing JavaScript apps.

Example demo @ Snack.Expo | Example repo @ GitHub

What we built

We needed to create a custom dropdown selector that would be placed in the application header that allowed the user to select an option from the dropdown to populate details on the main screen view. 

The header title area is created automatically by React Navigation when using createStackNavigator and updating the text is as simple as passing a title property. This is great for a basic display of titles, but for some screens we needed to extend this functionality to include a custom component that interacted with the main screen view. 

We knew some customization would be needed beyond what the library included by default. By using the available React Navigation API we were able to come up with a solid solution.

In short, we needed a solution to do the following:

  1. Display a dropdown toggle in the React Navigation header

  2. When the dropdown toggle is selected: Display a screen overlay with the selection options

  3. When the dropdown toggle is selected: Hide the tab navigation

  4. When a selection is made: Update the wallet data on the screen

Initialize React Native Project

Things on the internet change quickly so if these steps no longer work then dig into the React Native “Getting Started” guide to discover the bleeding edge 💉 way to get a RN project up and running.

  1. Run expo init YourProjectName

  2. If prompted: Select the option with minimum dependencies

  3. Cd YourProjectName

  4. yarn add react-navigation

  5. yarn add lodash

  6. Run yarn start

Setup the app with minimum dependencies

Basic Setup with Tabbed Navigation

Before we get started with any custom features we need to first set up the basic app navigation. The example app will have a few basic tabs using createBottomTabNavigator and each tab will have a Stack Navigator using createStackNavigator.

1. Add Navigator.js to components/navigation/Navigator.js

2. Add Screen.js to the components directory

3. Update App.js to initialize the navigation at the root of the component structure

Fancy tabs

After adding and updating just a few files, the look of the app has been transformed. We’ve set up the basic app structure and added a few example tabs. You should now be able to click the navigation items at the bottom to move between tab screens.

Now that the basic app setup is complete, we can move on to customizing the functionality

Add the dropdown to the header

1. Add HeaderDropdown.js to the components directory

This is the component that will be used in the header title area as the dropdown toggle.

2. Add the dummy data walletData.js to the project root

3. UpdateTAB_WALLET in Navigator.js to add the custom dropdown header for the Wallet screen. Add the code block between Start Here and End Here.

This will replace the default title under navigationOptions with a custom headerTitle component. This component can be anything but in this case we are using the HeaderDropdown component we added to the project.

Ignore selectedWalletId for now as we’ll go over that in the next step and the title will default to the first item in the WALLET_DATA array.

You can now see the HeaderDropdown component displayed in the header title area. If you click the component, it will toggle the dropdown icon but nothing else will happen yet.

Update the wallet screen to display wallet details

1. Add WalletScreen.js to the components directory

In WalletScreen.js the params isWalletDropdownVisible and selectedWalletId are being evaluated to to get the current state of the WalletScreen. There is also a function handleSelectWalletCard that is passed to the WalletCard. This function is called when a WalletCard is selected and is responsible for updating the route params. These route params are then accessed by the other components to update the UI elements.

2. Add WalletDetails.js, WalletCard.js and Badge.js to the componentsdirectory also

👆These files are simple display components and aren’t necessary to highlight in this example. They can be copied from the components directory in the GitHub repository.

3. UpdateTAB_WALLET in Navigator.js once again with the following changes. Add the code block between Start Here and End Here

Don’t forget to import WalletScreen at the top of Navigator.js.

We are now using the WalletScreen component in place of just the generic Screen component for the Wallet screen. We’ve also set up the route to pass the selectedWalletId

You can now see the list of wallets displayed in the main view. Selecting one of them will update the wallet details content in the main view. Pretty cool but we aren’t done yet! 

Hide the navigation tabs when the dropdown is open 🔥🔥

The dropdown content is now displaying when we select the dropdown toggle from the header but we need to take this a step further. 

In our app at TokenSoft, we wanted to remove the tab panels when a user is making a selection for 2 reasons: 

  1. To make the UI less busy and restrict the user paths that could be taken when the dropdown content was displayed.

  2. To allow for more screen space to be dedicated to displaying the dropdown content for smaller screens.

Update TAB_WALLET in Navigator.js once again to include the logic to hide and show the tab navigation. 

We are using .get from Lodash for the sake of brevity and because I’m lazy. Please don’t @ me.

In navigationOptions for TAB_WALLET we are getting the route name Walletand checking the param isWalletDropdownVisible then returning the result to the navigationOptions. When the isWalletDropdownVisible is updated, the tabbed panel visibility is toggled accordingly. 👌

Questions or stuck on something?

Check out the finished product in this Expo Snack or check out the repo on GitHub. If you are still stuck feel free to reach out with any questions.