(This article is part of an ongoing series on technical and soft skills from Nathan Thomas, a full stack software engineer studying and working at Lambda School based in Silicon Valley. Click here for part 5 in the series, an article about “The Pursuit of Persistence and Grit.”)
It’s time for another to-do app tutorial!
Just kidding.
I can guarantee that this walkthrough will be worth your time, much like double-stuff Oreos or a happy golden retriever puppy. We’ll be building out a simple weather app in React Native using MetaWeather, a free weather API. React Native is a library for building iOS, Android, and most recently Windows, tablets, and Xbox applications.
Here’s an example of the finished product we’ll be making. I’ve even thrown in a higher order component and some light styling for some extra seasoning so you can see that React Native isn’t so crazy after all.
As always, I like to define my reader expectations up front; you need to be familiar with React, as I won’t be explaining concepts fundamental to it. In fact, your ability to quickly learn React Native from this article depends on us being able to compare what we’re doing to how we would normally use React. Additionally, you need to be familiar with Flexbox and the basics of CSS. Lastly, it would also be great if you’re used to working with APIs, but it’s not a requirement; I’ll hold your hand through that part and give you the code for everything.
With that out of the way, let’s go ahead and get started. I think you’re really going to have fun with this one.
“We take better care of our smartphones than we do of ourselves — the phones are always recharged!”
— Arianna Huffington
There are just a couple things we need to do before we code anything. I’ll list them all out here:
When you’re done with both of those things, create a new, blank project in Snack. Your new boilerplate app should look something like this:
Snack makes up amazing names when you create a new application. Mine’s called “intelligent donut,” but yours might be something like “amused pistachio” or “frisky blueberries.” Go ahead and rename it if you want (although I’d personally keep either of those last two names), and then hit the big “Save” button in the top right corner. I’m going to call mine “React Native App Demo” for the sake of clarity during this walkthrough.
Go ahead and delete everything in App.js and paste in the following code:
<a href="https://medium.com/media/383fc891b3a4b19a0ddf0a0353e4b367/href">https://medium.com/media/383fc891b3a4b19a0ddf0a0353e4b367/href</a>
This is instantly going to throw an error because we haven’t created a HomeView component yet, but don’t panic from the red screen of death Snack is going to throw us. Let’s take a moment to discuss what’s going on with our code, and then we’ll go fix it.
Notice how I’ve only imported the react dependency so far. If this doesn’t prove to you that you can easily learn how to use React Native coming from a web background, I don’t know what will. We are running full-blown React on a mobile device, and we’ll supplement it in just a minute with the react-native dependency for anything else that needs to be tweaked to make it work.
With that little pep talk out of the way, go ahead and remove all the files in the existing components directory, add a container directory inside that one, and make a new HomeView.js file to go inside it. Paste in the following code (and then we’ll discuss it):
<a href="https://medium.com/media/1d18eadc3ba355b0b180404d04d588f4/href">https://medium.com/media/1d18eadc3ba355b0b180404d04d588f4/href</a>
Did you read through all of that? Good. You deserve a medal, high five, or at least a cookie 🍪 from someone. Go ahead and take a quick mental break to swig some of that hot beverage you’re holding.
Okay, let’s discuss what’s happening.
First off, we have the import line for react-native. It looks like this:
<a href="https://medium.com/media/161f9f3a557ec3213da1f0fe35a354b8/href">https://medium.com/media/161f9f3a557ec3213da1f0fe35a354b8/href</a>
These named exports from the react-native dependency allow us to build out our mobile application on top of normal React. But don’t be intimidated by them; they directly correlate to pretty much everything you already know about the web environment:
Taking that knowledge, let’s work our way down the page and analyze the code. To start, here’s the class in our HomeView.js component file:
<a href="https://medium.com/media/f26f6b9a5ebdce319562ced25357ec44/href">https://medium.com/media/f26f6b9a5ebdce319562ced25357ec44/href</a>
As you can see, we have our class structured with a ScrollView as the overall container. This allows us to have a scrollable, fluid structure to the page that the user can drag through with their finger. Inside of that, we have our View and Text tags which contains some text content. Finally, the last thing to note here is that we’re using another Text tag inside of the first one; this functions (in this scenario) very much like if you had a span tag inside of a p tag in your JSX in normal React. It allows you to single out parts of the text for specific styling.
We have our StyleSheet below our class. As a reminder, this is what it looks like:
<a href="https://medium.com/media/873103a28a604bb895c4318c04908e14/href">https://medium.com/media/873103a28a604bb895c4318c04908e14/href</a>
When we call StyleSheet's .create() method, we can pass in an object that contains multiple key-value pairs of styling objects. React Native connects these to our component and makes them accessible for reference there.
In the code snippet, the scrollContainer style is assigned the value of an object with many individual CSS styling properties inside of it. These are all camel-cased (i.e. marginBottom and justifyContent), and any text value is wrapped in quotation marks (i.e. "center", "spaceBetween", etc.).
Additionally, notice that all measurements lack the values (i.e rem, px, etc.) that you know and love (and maybe hate) from a web environment. This is because all measurements in React Native default to plain integers without a unit type ending. These represent pixel-density-independent proportions on the screen.
This is also a great moment to talk about how layout work in React Native. I’ve previously said that CSS is the technique you use to style everything, but you’ll also be pleased to know that Flexbox is the module we use for all layouts. There are two significant differences with it that you need to know about right now, though:
As we previously said, the object passed into StyleSheet.create() applies to the component when it mounts. We then utilize the styles on it by writing style={styles.styleNameGoesHere} on the component in the code; here’s the HomeView.js class again so you can see what I’m talking about:
<a href="https://medium.com/media/f26f6b9a5ebdce319562ced25357ec44/href">https://medium.com/media/f26f6b9a5ebdce319562ced25357ec44/href</a>
Pretty cool, right?
Now that we have a basic grasp on some of the React Native imports as well as how the default stylesheets work, let’s go ahead and rig up a higher order component, some presentational components, and make an axios call to our MetaWeather API.
“When we started work on the iPhone, the motivation there was we all pretty much couldn’t stand our phones, and we wanted a better phone.”
— Jony Ive
At this point, your app should have the following image on screen and file setup as shown below:
We’re going to go ahead and build out the rest of this app. I’m going to show you entire snippets of code to paste in, and we’ll talk about anything unique before we move on to the next one. Sound good?
First, create a LoginView.js component inside your container directory and paste in the following code:
<a href="https://medium.com/media/7cd1e1cb6f5daf04fb87de0829557548/href">https://medium.com/media/7cd1e1cb6f5daf04fb87de0829557548/href</a>
This only new thing I want to point out here is that we can import and use the prop-types dependency just like in normal React. We won’t be doing that in the rest of the application, but it’s important that you at least see it once. Now we have to go flesh out the rest of the app so that this component's buttonFunction will get passed in on props.
That code above is also going to throw a big red error due to the button import, so create a presentational directory inside the components one and make a Button.js file there. Paste in the following code:
<a href="https://medium.com/media/632b5603c500581f430744af6b649f60/href">https://medium.com/media/632b5603c500581f430744af6b649f60/href</a>
In this code, I want you to notice what we’re importing from react-native— TouchableHighlight is what allows React Native to respond properly to touches when wrapped around other tags. We have to supply it with an underlayColor prop and a hex color code (the last two numbers of the #0E30F050 above are the opacity percentage). If we don’t supply this, the color will turn super funky when we press the button (read about why here).
Additionally, notice that we no longer have onClick events. Instead, we’re using onPress which seems super obvious if we stop to think about it. We are using smartphones, after all!
Our next step is to make one more file in your container directory. We’ll name it authenticate.js. This is a higher order component for an extremely simple pseudo-login process. Paste this code in:
<a href="https://medium.com/media/0dd833be919505acd6c178aab8111f85/href">https://medium.com/media/0dd833be919505acd6c178aab8111f85/href</a>
The point of using a higher order component and some light currying is to show you that we’re flexing the exact same muscles as in normal React. React Native isn’t that bad, and things are really starting to come together now!
Obviously, we need to complete the circle with our components, and you can probably see where this is going if you’re used to currying and higher order components in React; let’s go back to App.js and update it to look like this:
<a href="https://medium.com/media/334b4fee5c66ab82c9349430857d8f0f/href">https://medium.com/media/334b4fee5c66ab82c9349430857d8f0f/href</a>
Right on! At this point, our file structure and application should look like this:
If you click that beautiful blue button, you will “login” to your application. It’s time to make our call to the MetaWeather API and display our data to the screen!
Image by Alfred Twj on Unsplash
First, go ahead and click on the package.json file. Delete all the code in there, and paste the following dependency list in:
<a href="https://medium.com/media/34ce9193aabaf9db14665d017692d597/href">https://medium.com/media/34ce9193aabaf9db14665d017692d597/href</a>
Isn’t it nice to know that we have ye olde package.json with us and along for the ride?
Next, go to HomeView.js and update the code to look like this:
<a href="https://medium.com/media/4a4229ffafc937b1cd19a72d8d1d9100/href">https://medium.com/media/4a4229ffafc937b1cd19a72d8d1d9100/href</a>
We just imported the axios dependency along with the Button.js component, added a class constructor function, implemented a componentDidMount() lifecycle method, but some new text and a button in our component code, and added a weatherText style in our StyleSheet code. The axios call happening in our lifecycle method is currently coded to San Francisco, but you can tweak it using the information in the MetaWeather API documentation here.
Whew. 😰
That was a lot of work, but we’re all done! Poke your way around the application, and you’ll find that you can log in, drag the ScrollView page from HomeView.js around, render the current weather to the screen, and logout using the button on the home screen.
Thanks for reading.
Nathan
(GitHub, LinkedIn, Twitter, Instagram, and Portfolio Site)