A clueless look at React Native (Part 3): developing a movie library app
Material design, navigation, persisting state
After setting up the environment in Part 1 and creating a very simple first application in Part 2, I was ready for something slightly more ambitious.
For my second project with React Native, I wanted to make something that forced me to explore more APIs and libraries. At the same time, something not too complex, since I didn’t want to get lost in a big project I would never complete.
In the end I decided to go for a Movie Library app, where you can search for movies, read their details such as the plot and add them to your library of movies.
Obviously I needed some inspiration, so I headed over to the Google Play Store and eventually found the perfect app I was looking for. I loved the material design and the functionality, thus I wanted to see if I was able to replicate at least its core concepts.
For retrieving movie data I used the OMDb API. It is an open API that is free to use, most movie metadata also includes the poster image. However is a bit limited in term of search, you can pretty much only search by title.
You can find the completed project on GitHub: react-native-app-movies
Let’s see which were the main challenges that I had to overcome in many clueless ways (AKA Google Search + Stack Overflow + GitHub).
Material design
The main thing to implement was material design, so I looked for existing libraries on GitHub.
There were a few available with lots of stars:
To me, react-native-material-ui looked like the most simple and actively maintained library, thus in the end I headed for it.
Sure, the documentation is quite basic and I had to look at the source code several times to understand how things were implemented, but this also happened with other react-native libraries 😃
That being said, the code looks very well structured and well written, thus going through it didn’t feel like a chore.
Navigation
Initially I wanted to use react-native-navigation, but then I discovered that it isn’t really supported by Expo, which instead uses react-navigation.
Plus, react-native-navigation requires messing with native modules and seems to have a higher learning curve.
In the end, I loved react-navigation! It is pretty much a must for me at this point.
What I didn’t know is that it can also do things like adding a navigation drawer, which is exactly what I needed. This can be achieved by using createDrawerNavigator.
However, I wanted to use the Drawer component provided by react-native-material-ui. Luckily, react-navigation allows custom Drawer components:

NOTE: for the drawer header background I used one of the material wall images posted in https://plus.google.com/+BrianParkerson/posts/QGcBs3E9D4B
Initially I just used the drawer navigator but then I noticed that when executing this.props.navigation.goBack() to go back to the previous route it was instead always going back to the home route.
Some stack overflow searches later I learned that I also needed to use createStackNavigator, by combining it with the drawer navigator.
This can be done with code such as the following
Note that the stack navigator automatically adds a header to the top of the screen, which I didn’t need as I was already using the Toolbar component from react-native-material-ui.
Thus, I had to use header: null to hide it.
Tabs
I had to implement the “My list / Favorites” tabs, but the material library I was using didn’t provide a Tab component, so I needed another library.
Eventually I found react-native-tab-view, which works very well out-of-the-box.
It also has built-in animations such as changing the current tab with swipe gestures!

Fitting images
The OMDb API returns poster images of variable size. I needed a way to fully display those images, without knowing their size beforehand.
Initially I tried using the regular Image component and auto/percent widths, but they weren’t working. Images were only expanding up to the existing container height, instead of expanding the container to fit them.

I still have a lot to learn in this area, maybe I’m missing something, I also looked at some react-native issues on GitHub, which pretty much suggest using external libraries.
The suggested library I ended up using is react-native-fit-image.
It works and does its job, it also has built-in loading indicators, however library development seems stale (latest commit being from Nov 2017).
Important things seem missing, such as handling errors (as far as I’ve seen). For the next project I might look at some alternative.
Persisting state
This is a feature needed to prevent saved movies from disappearing when reloading the app.
There are several options to achieve this, but since the app uses redux, the simplest way seems to be using redux-persist with the default AsyncStorage provided by react-native.
There is a limit of 6 MB of storage in current Android versions, it is more than enough for my use case, but I might have to look at something more robust for future applications.
Take a look at store.js for my implementation.
Bonus: wipe all
Lastly, I wanted to implement a “wipe all data” feature to completely clear both persisted and local data.
I knew that to clear persisted data it was enough to call persistor.purge()But what about the local state? Basically I needed a way to reset the redux state to whatever initial state I had defined in my reducers.
The usual quick google search led to this great answer by Dan Abramov, the (co-)creator of redux.
Basically you can wrap your combined reducers into a root reducer that, when receiving an action such as ROOT_RESET,sets the state back to undefined.
This way each combined reducer will then return the initial state.
Going further
What’s left? Developing more and more apps for sure!
I also want to look at the publishing phase, i.e. actually hitting the app store. To do that I need to figure out something decent to make. It might be a real challenge 😃
Be sure to wait for the next article(s) to find out what went wrong, and how I managed to overcome issues in more clueless ways!
