Tutorial

Building a Landing Page in React Native Using Flexbox

Published on July 26, 2018
Default avatar

By Holly Girouard

Building a Landing Page in React Native Using Flexbox

While we believe that this content benefits our community, we have not yet thoroughly reviewed it. If you have any suggestions for improvements, please let us know by clicking the “report an issue“ button at the bottom of the tutorial.

Styling a React Native app can be quite painful if you aren’t familiar with its styling powerhouse: the Flexbox layout module. While we can style with JavaScript, understanding and implementing Flexbox layout is an absolute essential for UI development with React Native. In this walkthrough, we’re going to build a landing page using Flexbox.

Spoiler alert, we won’t implement Flexbox until the end!

About Flexbox

You’re probably already familiar with flexbox layout with CSS, and React Native’s implementation of Flexbox is almost the same. Flexbox is a powerful and efficient styling tool optimized for building user interfaces, especially for mobile interfaces. By using the flex property in a component’s style, we can enlarge and shrink dynamically based on the space available.

The flex property in React Native is a little bit different than with CSS, and instead works a little more like the fr unit in CSS, where the number value provided represents a proportion of the space taken. So in React Native flex expects just a simple number value.

Aside from the flex property being different than with the CSS flex shorthand property, the other difference between React Native’s implementation of flexbox and the CSS implementation is that the flex-direction defaults to a value of column in React Native.

Let’s Do It

In our example project we’re going to build a landing page for AlligatorChef 🐊, the number one fictional source for cajun bacon recipes since 1987.

Here’s how our project should look when we’re finished:

AlligatorChef 🐊 Voilà!

🐥 If you’re new to React Native, our tutorial Getting Started with React Native and Expo is a stellar way to prepare for this tutorial.

🚀 React Native Quickstart

In your terminal run the following commands to create a new React Native project, change into the new directory, initiate the project and then enter i for iOS.

$ create-react-native-app AlligatorChef
$ cd AlligatorChef
$ npm start
$ i

What Do We Have Here?

We can already see an example of Flexbox being used in the initial code obtained with Create React Native App with the use of the flex poperty in the call to StyleSheet.create. Take a look at the App.js file. Seems like they might be giving us a hint that Flexbox is key to styling in React Native:

App.js
const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#fff',
    alignItems: 'center',
    justifyContent: 'center',
  },
});

This is telling us that the container should stretch to fit the entire screen.

Next steps

Now that we have our default project, let’s make a few modifications.

Let’s first add two Text elements for our headers.

Replace:

<Text>Open up App.js to start working on your app!</Text>
<Text>Changes you make will automatically reload.</Text>
<Text>Shake your phone to open the developer menu.</Text>

With:

<Text style={styles.h1}>AlligatorChef</Text>
<Text style={styles.h2}>Providing cajun bacon recipes since 1987.</Text>

Not much to look at, right? Let’s add some styles in the StyleSheet to spice it up. In one big swoop, replace everything you have with the following styles, including the default container. Your StyleSheet should now look exactly like this:

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'space-between',
    backgroundColor: '#000',
    alignItems: 'center',
    width: '100%',
  },
  h1: {
    color: '#008F68',
    fontSize: 40,
  },
  h2: {
    color: '#FAE042',
    fontSize: 18,
    marginTop: 8,
  },
});

Let’s talk a little bit about what we just changed. You probably noticed the colors and fonts, but there’s one sparkling example that will explain why your app is looking a little spacey.

We changed justifyContent from center to space-between. If we change it back to center, everything will look happy and centered again, but we have much more to add. When using justifyContent: 'space-between' we’re getting each item spaced evenly between the top and the bottom of the screen. This is why our h1 is glued to the top and h2 to the bottom.

Images and Buttons

Rather than remedy this immediately, we’d prefer to create a little more chaos. Let’s go ahead and add an Image and a Button.

Replace your current code with the code below, while keeping the styles declaration:

import React from 'react';
import { StyleSheet, Text, View, Button, Image } from 'react-native';
import Logo from './assets/chef.png';

export default class App extends React.Component {
  render() {
    return (
      <View style={styles.container}>
        <Text style={styles.h1}>AlligatorChef</Text>
        <Text style={styles.h2}>Providing cajun bacon recipes since 1987.</Text>
        <Image
          source={Logo}
          style={styles.image}
        />
        <Button
          title="LET'S START"
          style={styles.button}
          onPress={() => this.onPress()}
          color="#fff"
        />
      </View>
    );
  }
}

// ...

Next, in the root folder, create a folder called assets. Generally we like to keep images in an assets folder to be easily accessible to all components in our project. Add the image file you’d like to use as your AlligatorChef 🐊 logo to this folder.

React Native is a bit fickle with images and might give you some issues. For this use case, make sure you’re using a png image.

Without Flexbox

Oof. Not quite what we were wanting, right? 🌵

Styling

Now that we have all of our elements, they look a little sad. Let’s fix that.

Images in React Native need a size

As a best practice in React Native, we always need to give our images a size. If you’re ever having an issue with an image not showing up, ensure that you’re assigning it a size. As you can see, we already gave the image a class in its style prop so let’s give that class some attributes. In your StyleSheet add the lines below to tame that big ole’ gator.

image: {
  width: 300,
  height: 260,
  justifyContent: 'center',
},

He looks much more manageable now!

My button doesn’t look like a button!

React Native buttons are quite picky as well. Rather than having an opening and closing <Button> with text between, React Native requires a title prop. If you look at the supplied code above, you’ll notice we included that to avoid some errors.

React Native requires us to send-in props to the Button, but it also requires us to create a style for the View that contains the button. Let’s go ahead and add a container and a class to our StyleSheet.

First add a View with the class of buttonContainer to your code:

<View style={styles.buttonContainer}>
  <Button
    title="LET'S START"
    style={styles.button}
    onPress={() => this.onPress()}
    color="#fff"
  />
</View>

Next, add the following to your stylesheet:

buttonContainer: {
  backgroundColor: '#008F68',
  borderRadius: 5,
  padding: 8,
  margin: 8,
},

Button styling

That looks a lot more like a button!

Are You Ready for Some Flexbox?!

Okay, let’s get the rest of this page under control by using the magical Flexbox. Ya’ll ready for this? 🏀

We’re going to start by adding three containers within our original container. If you replace your initial code with the following, you’ll notice a few new classes, topContainer, middleContainer, and bottomContainer.

import React from "react";
import {
  StyleSheet,
  Text,
  View,
  Button,
  Image,
  ProgressViewIOS
} from "react-native";
import Logo from "./assets/chef.png";

export default class App extends React.Component {
  render() {
    return (
      <View style={styles.container}>
        <View style={styles.topContainer}>
          <Text style={styles.h1}>AlligatorChef</Text>
          <Text style={styles.h2}>
            Providing cajun bacon recipes since 1987.
          </Text>
        </View>
        <View style={styles.middleContainer}>
          <Image source={Logo} style={styles.image} />
        </View>
        <ProgressViewIOS number={1} />
        <View style={styles.bottomContainer}>
          <View style={styles.buttonContainer}>
            <Button
              title="LET'S START"
              style={styles.button}
              onPress={() => this.onPress()}
              color="#fff"
            />
          </View>
        </View>
      </View>
    );
  }
}

Let’s add these classes to our current StyleSheet to see some magic.

topContainer: {
  flex: 2,
  justifyContent: 'center',
  alignItems: 'center',
},
middleContainer: {
  flex: 3,
  justifyContent: 'flex-start',
  alignItems: 'center',
},
bottomContainer: {
  justifyContent: 'flex-end',
  width: '90%',
  margin: 20,
  padding: 10,
},

Alligator Chef 🐊

✨MAGIC!✨

Let’s discuss how Flexbox saved the day

We assigned flex: 2 to topContainer, giving it a flex-grow value of 2, so that it takes 2/5ths of the original container. We also told it to align and justify everything in the center. Take a look at the screenshot below for a visual demo.

2/5ths Example

We assigned flex: 3 to middleContainer to take the remaining 3/5ths of the original container. Rather than using justifyContent: 'center', we instead used justifyContent: 'flex-start'. This is why our AlligatorChef 🐊 image is aligned to the top of middleContainer.

3/5ths Example

Lastly since we aren’t concerned with how much of the page the Button takes up, we do not need to specify a flexBasis. We only need the button to be at the bottom of the page, so we assign bottomContainer justifyContent: 'flex-end'.

That’s it 🐿

Though this is just a general introduction, the Flexbox layout module has a ton to offer for not only React Native but general web development.

👉 Always remember to look for easter eggs. 🤓

Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases.

Learn more about us


About the authors
Default avatar
Holly Girouard

author

Still looking for an answer?

Ask a questionSearch for more help

Was this helpful?
 
Leave a comment


This textbox defaults to using Markdown to format your answer.

You can type !ref in this text area to quickly search our full set of tutorials, documentation & marketplace offerings and insert the link!

Try DigitalOcean for free

Click below to sign up and get $200 of credit to try our products over 60 days!

Sign up

Join the Tech Talk
Success! Thank you! Please check your email for further details.

Please complete your information!

Get our biweekly newsletter

Sign up for Infrastructure as a Newsletter.

Hollie's Hub for Good

Working on improving health and education, reducing inequality, and spurring economic growth? We'd like to help.

Become a contributor

Get paid to write technical tutorials and select a tech-focused charity to receive a matching donation.

Welcome to the developer cloud

DigitalOcean makes it simple to launch in the cloud and scale up as you grow — whether you're running one virtual machine or ten thousand.

Learn more
DigitalOcean Cloud Control Panel