Table of contents
React Native is awesome! However, you can waste some time in the most unpredictable places. The goal of this article is to share own knowledge on developing the app on React Native and save your time on app development.
It’s our second part of React Native article. Please check Part 1 (How we build apps using React Native).
There are too many implementations of navigation to React Native, we can divide them into three categories:
We prefer to use react-native-navigation made by WIX in our projects. It is a fully-featured navigation, which includes all critical components like navbars, tab bars and side menu drawers. It provides great user experience for iOS and Android platforms, including native animations, etc.
However, there are a few things you should know before starting to build React Native app.
You can set a custom width for the drawer, but you should know there are some differences for platforms. In Android platform, you can set the width in React Native pts., in iOS platform in percents from the full-screen width. Note it, if you should have custom fixed drawer width by the design.
We are using React Native Drawer to handle these cases.
Tab bar customization
In case you need to set custom height for the TabBar, bear in mind — there is no way to do it easily. Want to redefine click on the tab? Not so easy! Sure, you can do it, but be ready to go deep into native code!
Not all features of navigator are documented, so do not be afraid to open source code of react-native-navigation and check it on your own.
Image scaling in React Native app
Creating combined images in React Native app is quite a challenging process. If you have 2 images and want to unite them, then obviously you will resize or scale them. According to documentation about React Native Images, you need to use resize Mode props(‘cover’, ‘contain’, ‘stretch’, ‘repeat’, ‘center’). There you can find everything for scaling, but if you want the image to inherit parents size, there is no solution.
To make it you should use `width: null` as style of your image. Weird? Yes, but this thing works :)
Development of animated lists
A lot of applications use some kinds of lists. To create a list in React Native you can use FlatList or SectionList. If you are working with lists and want to add some animations, for example, scrolling to element when the list is loaded, just take a look at this line in the documentation:
In order to constrain memory and enable smooth scrolling, content is rendered asynchronously offscreen. This means it’s possible to scroll faster than the fill rate ands momentarily see blank content. This is a tradeoff that can be adjusted to suit the needs of each application, and we are working on improving it behind the scenes.
It means that rendering list action will be at the end of the asynchronous actions queue after mounting the component. So the workaround for this is to push function that performs animation to the end of the queue. It can be performed by using:
In this case animation function runs only after list is fully loaded.
Redux-persist — Offline first app
One of the main purposes of our app was to create a product by using which user won’t feel if he has internet connection or not. So if there is no Internet or the connection is lost, a person will continue using app as earlier. The thing that helped us is redux-persist. It can be configured to automatically persist Redux state updates to disk using React Native’s `AsyncStore`. It’s quite straightforward and GitHub readme file (link here) will help to add it successfully.
One confusing issue is border-radius. Usually, borderRadius is applied to get rounded corners for a View. There are many views with rounded corners like speech bubbles, buttons, card containers, etc.
All these views with rounded corners behave differently on iOS and Android platforms. Few elements do not have top corners, few don’t have bottom corners, or View is rounded in the Android platform and not rounded in the iOS platform. There is no consistency.
The solution for this issue is just to apply overflow: 'hidden'. A quite simple solution but takes time to figure it out because of its inconsistency.
Handling application orientation
Handling orientation is one of the common tasks in mobile development. Sometimes, we need to disable landscape orientation in the app. It can be done without any specific React Native features.
For Android just add:
In Xcode, General tab, Device Orientation box.
However, there are few issues we faced related to handling orientation.
First is related to `react-native-navigation`.
Note: standard orientation disabling methods do not work with it. You have to manage this in `appStyle` or `navigatorStyle` object while configuring `react-native-navigation`.
Another issue we faced was enabling screen rotation only in specific screens. `React-native-orientation` is the best solution for this. It allows to lock and unlock orientation rotation on specific screens, get current location and lock on specific orientation. But!
You may face the interesting bug related to this package. If your main app content is developed only for vertical orientation and you have some components, which take their width and height depending on the screen width and height you should definitely test the case when the app is launched in horizontal orientation of the device. The splash screen of the app (in iOS) can be rotated from a vertical orientation to horizontal. But shouldn’t! To fix this issue add next code to project AppDelegate.m file
One more tip you will not find in the official documentation of React Native is about background images. There are few ways how to set up background image for your screen.
One way is to use <image> component inside the <view> with next styles:</view></image>
But other, still not documented way is to use ImageBackground imported from ‘react-native’ package. It can be used in a next way:
React Native is too young now. There are no established approaches to creating applications with React Native. We hope that our info helps you to learn and save development time in the future.