Building a Reddit Image Search App with React Native

I’ve been learning React Native for about a week now. In the process, I’ve developed a Subreddit Image Search App. In this tutorial, I’ll try to share what I’ve learned so far to help beginners build their first app. Beware, it’s not one of those tutorials you find on Web from experienced react native folks with full of best practices and shiny fluid UIs. I just tried to make it work, and might not have used the best practices or patterns. And I’m in no position to infer what best practices are, after just a week of learning. I’ve set up a Github repository if you want to directly dive into code without going further.

Getting Started

There are two ways to create a react native app, create-react-native-app and react-native-cli.  Apps created with create-react-native-app does not need any build tools (Xcode and Android Studio). Simply create an app and run it in Expo Client on your Android or IOS phone. On the other hand, react-native-cli require Android SKD and Xcode to build and run your apps. We’ll use CRNA to create our app. Later on, I’ll show you how to eject your CRNA app to generate a custom build and explain the need for it.

Creating and Running React Native App

I’m assuming that you’ve already installed Nodejs.

Run  npm install -g create-react-native-app to globally install CRNA. Now create a new app and name it reimg.

React Native packager will package your app and show you a few options.

Scan QR code option is no longer available on IOS Expo Client. Press s and enter your email address. You’ll receive an email with expo link. You’ll be redirected to your browser after clicking on Expo link. It will ask you to open it in your Expo app. After accepting, your app will run in Expo client.

Installing Dependencies

Let’s discuss dependencies. We’ll use react-native-axios to make network requests. react-native-elements is a cross-platform UI toolkit. We’ll use it to keep our components look exactly the same on both IOS and Android platform. We’ll use react-native-flex-image to render images in full width, I’ll later explain the need for it. react-navigation is a community developed solution for routing and navigation between components in react native apps. And at last, we’re using url, a small package for parsing URLs.

App Components

Let’s dive into the code and create these components.

  • App
  • Search
  • Results
  • NotFound

App components come pre-created with CRNA app. We’ll render stack navigator Components in the render method of App component.

Stack Navigator provides a way to transition between components. With initialRouteName property, we can specify which component gets rendered on initial app load. We have two screens in our configuration, Search component will render a form where a user can enter a subreddit for image search. Result component will render images and NotFound will be rendered in case subreddit doesn’t exist.

In Search components, we’re rendering a logo Image, an Input, and Button for search. We’re rendering KeyboardAvoidingView instead of a simple view to move out of the way of virtual keyboard. We’re assigning null to static  navigationOptions property to hide default header. We are validating state on button press and navigating to Search component with subreddit prop. This is how our Search component looks like.

When our Results component mount, we’re assigning header title with subreddit prop from navigator. In our componentDidMount()  method, we’re calling getImages() method to retrieve posts from subreddit. After receiving posts, we’re filtering media posts. If it’s an image, we add it to our local images array. If it’s an link, we generate an imgur API URL based on its type. We’re generating axios promises array from filtered imgur links.

After retrieving results from axios promises, we’re adding URLs to our local images[]  array. We’ll then update our component state with received images. In render()  method we’re rendering ScrollView to render Images with titles. FlexImage component is a wrapper for native Image component for rendering an image in full width and auto height.

ActivityIndicator component can be passed to FlexImage to show a spinning loader when an image is loading. We’re rendering a load more button. When pressed it calls getImages()  method with new params to retrieve next page results. And in the end, we’re rendering a NotFound  Component to handle a case where Subreddit doesn’t exist.

Ejecting from CRNA

Running yarn eject converts your CRNA app to react-native app. It would be the same as if you created an app with react-native-cli init command. CRNA apps help you get started quickly, but if you want to distribute your application or write a piece of native code at some point in development,  you need to eject it. Read more about in docs.

Create React Native App makes it easy to start working on React Native apps by removing native code build tools from the equation. However, many apps want functionality that comes from interfacing directly with mobile platform APIs via Java, Objective-C, Swift, C, etc. As of right now, the only way to get direct access to these APIs from your app is by “ejecting” from CRNA and building the native code yourself.

To generate a signed apk for your ejected app, please refer to this guide. I’ve set up a repository. You can clone it right now and start hacking it. If you get an error or wants to ask something, please leave a comment and I’ll try to answer it.

Share this post

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.