Tutorial

Learning the Basic Components of React Native

Published on January 15, 2020
Default avatar

By Stephen Hartfield

Learning the Basic Components of React Native

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.

React Native works a lot like React, implementing JSX, state, and props. Of course, React Native is built on Native components, instead of HTML elements. Therefore, if you are familiar with normal React, it will be easy to pick up React Native, as long as you can understand the different components used. In this guide, we will look through the basic Native components that React Native uses.

Unlike React for the web, React Native requires you to import each component in your project - after all, each component is setup to work both in Android and iOS. This is the reason we use React Native, not to mention being able to write everything in JavaScript. To import each component, we will simply add it to our imported object:

import { Text, View } from "react-native";

Text and View are the two most basic building blocks of any React Native application. They are the best place for anyone to start when learning React Native.

Text and View

As you can guess, <Text></Text> is a wrapper for any text in your page. This component is similar to a <p> tag in HTML. Now, similar to a <div></div> tag, you would wrap your <Text></Text> in a <View></View>. That’s right, <View> acts very similar to <div>, and the basic idea is that it is a container perfect for dividing up and styling your page.

Here is the basic set up of a React Native page:

import React from "react";
import { View, Text } from "react-native";

export default class App extends React.Component {
  render() {
    return (
      <View>
        <Text> Hello World! </Text>
      </View>
    );
  }
}

Both <Text> and <View> components have style props where you can set colors, sizes, etc. However, there are some important distinctions to keep in mind. Although View does work similarly to a div element, you can’t wrap any text in it, like this <View>this text doesn't work</View> (not that you should with a div element anyway). That would cause an exception and that is why we use the <Text> component.

Speaking of the <Text> component, you can wrap another component inside it like this:

<Text style={{ color: red }}>
  <Text style={{ fontSize: 24 }}>Here is the first text </Text>
  <Text style={{ fontSize: 14 }}>And the second text.</Text>
</Text>

// comes out as 'Here is the first text And the second text'

When <Text> is wrapping <Text>, the nested text will come out on the same line, assuming there is enough space. However, if the two <Text> components were wrapped in a <View>, they would appear on separate lines.

TextInput

This component is somewhat like an <input> HTML element, but as its name would indicate, it’s only for a text input. Instead of using onChange callback, you can use onChangeText to detect changes to the text in the <TextInput> component. You can use onChange, but it returns an object: { nativeEvent: { eventCount, target, text} }.

Other than that, there are plenty of cool features on this component. You can set which keyboard pulls up on the phone with keyboardType (such as keyboardType='email-address'), toggle the auto-correct feature, set the textContentType for the phone to autofill the text (like your password on your keychain), and so much more.

Button And Alert

The <Button /> component is the first component I noticed that had major differences from its sibling (the HTML <button> element). The React Native <Button /> has an onPress() prop, as opposed to anything click-related. It also has a title prop for the text which goes inside it. Finally, it doesn’t have a style prop, but only a color prop.

That last point is a pretty big difference. Now you can (and would) wrap it in a View and style it with that wrapper. That is a common way to deal with some limitations on React Native components and you will likely find yourself using View to wrap other components all the time. What I find myself using more often is a component we will cover a little later - <TouchableOpacity >.

What I also found interesting about this basic Button component is that on the iOS platform, it only shows up as the text in the title - with no background. Therefore, the color prop will only change the text color, though on Android it will change the background color of the button.

Here is a quick example of a Button component.

<Button
  onPress={() => Alert.alert("button pressed!")}
  title="alert button"
  color="blue"
/>

Note: we are using Alert which is also imported from the React Native core. This will show an alert on top of our screen, similar to a web alert().

Image and ImageBackground

The <Image /> component is pretty similar to a HTML img tag. However, there are a few differences, such as changing the src prop to source. Also, the source itself operates differently: for local images, you import them with require, like this <Image source={require('path/to/local/image)} />.

Also, in the source prop, you can use the URI like this: <Image source={{uri: 'https://imagesite.com/path/to/image'}} style={{height: 100, width: 100, resizeMode: contain}}. Notice the uri is an object, so it needs another set of curly braces, just like inline styles. There are plenty of other props to check out here, but a common one to use is resizeMode. This determines how to resize your image and to fit your image within a parent View component.

The ImageBackground component is similar to the <Image /> component as it receives the same props, but the main distinction here, is that it can have child elements. The <Image /> component is self-closing. The thing about ImageBackground is, is that it’s pretty basic and a better solution to setting a background image might be to either build your own component or simply set an Image as absolute with lower opacity and behind everything.

The Touchables

One thing you’ll notice in React Native is that many of the components we have covered do not have all the props you would normally implement in a web app. The <Image /> component does not have an onPress prop and the <Button /> component doesn’t have a style prop. Any Touchable component can really help here.

For instance, you can wrap any image component in a Touchable:

<TouchableHighlight onPress={this.pressHandle}>
  <Image />
</TouchableHighlight>

The TouchableHighlight in the above example acts like a container for the image with a function when pressed, including a built-in animation. You could also just add View and Text components within a Touchable component to act just like a <Button />, but with customizable style.

Now there are a few different Touchable components such as:

  • TouchableHighlight: when pressed, darkens the background.
  • TouchableOpacity: when pressed, dims the opacity of the button.
  • TouchableNativeFeedback: Android-only ripple effect.
  • TouchableWithoutFeedback: a press without any feedback/effect.

These animations happen when pressed. The Touchable components also have their own unique props which you can customize to your own liking.

ScrollView, SafeAreaView and FlatList

So far we’ve looked at all the basic building blocks of a React Native app. However, there are plenty more, and one thing you will quickly find is that a phone screen won’t automatically scroll if the content height or width exceeds the screen size. This may surprise you, when you have everything wrapped in a View component, the overflow will be hidden.

That’s where the simple implementation of ScrollView comes in. The ScrollView component is the basic component to enable scrolling. However, FlatList also enables scrolling, but it has a much greater capacity than ScrollView.

Now, the basic setup of ScrollView is giving boundaries to the scrollable-view, which would most likely be the screen height and width. Like an image, you can wrap ScrollView to give it these boundaries. Normally, you can use a normal View component for this, but if you have an iPhone X, you may find that your View goes up behind the rounded corners or sensor cluster. The SafeAreaView will take care of this, giving adequate padding so the entire screen will be visible. Either way, to stretch the entire screen, you can simply set the style of the parent view to flex: 1.

This setup with ScrollView will work when the height of all your elements is determined locally - as in, the height of your page will always be set the same. If there is data coming in that affects the dimensions of the content, it may be difficult to determine the dimensions of the ScrollView. There are ways to compensate for that, but an even bigger limitation to ScrollView is that it will render everything all at once. Imagine your Facebook account rendering every story at once - it would never load!

FlatList is similar to ScrollView, but it uses lazy-loading, so that only the items which are currently on the screen will render. Of course, FlatList requires data to be passed to it. More specifically, it requires an array of data to be passed. Then, FlatList loops over that array and renders each one when on screen. If an item goes off the screen, when the user scrolls away, FlatList dumps that item and recreates it the next time it appears on the screen (state is lost). ScrollView, on the other hand, doesn’t dump and reload, but renders them all at once at the beginning.

Here is an example of each:

<SafeAreaView style={{ flex: 1 }}>
  <ScrollView>// content in here to fill the page</ScrollView>
</SafeAreaView>
<SafeAreaView style={{ flex: 1 }}>
  <FlatList
    data={dataArray}
    renderItem={(
      { item } // item would represent one element in the dataArray
    ) => <IndividualComponent prop={item.prop} />}
    keyExtractor={item => item.id}
  />
</SafeAreView>

Now, you wouldn’t ever want to nest FlatList inside a ScrollView or vice-versa. That isn’t good practice and it would give you an error anyhow. The important thing to keep in mind with FlatList is that the renderItem prop is fixed to take these parameters in its function: renderItem={({item, index, separators}) => {}}. Also, the item is always from the array you pass into the data prop - which can only take in a plain array.

A few other important things about FlatList - keyExtractor takes care of React’s need to set a unique key on each element, just like setting a key prop on each of the components rendered by FlatList. Also, if the dataArray updates because of state or another prop, the FlatList wouldn’t re-render as it is setup in the example above. In order to have it update, you could set the extraData prop to watch what would update (e.g. extraData={this.state}).

Wrap Up

That concludes the basic components of React Native. As you can see, they are much more particular than you might be used to. For more information on the components here, check out the official docs.

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
Stephen Hartfield

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