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.
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.
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.
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()
.
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.
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:
These animations happen when pressed. The Touchable components also have their own unique props which you can customize to your own liking.
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}
).
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.
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.
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!