go back

React Native

React Native

ReactNative.dev


What is React Native?

     React Native allows you to build native mobile apps without using native code. How is this possible? React Native can do this because it compiles the code to the native language of both Android and IOS devices, Java/C++ for Android and Swift for IOS. This means React Native is cross-platform, write your code once and run on any IOS or Android device. You write your app in JavaScript and React code that is very similar to the React code you would write for a web application. The big differences come inside the components, we use native components instead of web components in React Native. Also, you do not render HTML and CSS does not exist in app development.

Components in React Native

     Since there is no such thing as HTML in the native world, our JSX needs to render something that the device can recognize. We use Native Components to do this. A view is the basic UI building block, similar to a div in HTML. React native invokes these native views using the React Native Components. Here is the full list of Core Components, from the React Native Docs.

Basic Components

React Native UI ComponentAndroid ViewiOS ViewWeb AnalogDescription
<View><ViewGroup><UIView>A non-scrolling <div>A container that supports layout with flexbox, style, some touch handling, and accessibility controls.
<Text><TextView><UITextView><p>Displays, styles, and nests strings of text and even handles touch events.
<Image><ImageView><UIImageView><img>Displays different types of images.
<ScrollView><ScrollView><UIScrollView><div>A generic scrolling container that can contain multiple components and views.
<TextInput><EditText><UITextField><input type="text">Allows the user to enter text.

User Interface

React Native UI ComponentWeb AnalogDescription
<Button><button>A component for handling touches.
<Switch><input type="checkbox">A toggle switch that renders a boolean input.

List Views

React Native UI ComponentWeb AnalogDescription
<FlatList><ul>A list that only renders elements currently showing on the screen, making it more performant.
<SectionList><ul>Similar to a FlatList, but use if you have multiple sections in your list.

Others

React Native UI ComponentDescription
<ActivityIndicator>Displays a circular loading indicator.
<Alert>Launches an alert dialog with the specified title and message.
<Animated>A library for creating fluid powerful animations that are easy to build and maintain.
<Dimensions>Provides an interface for getting device dimensions.
<KeyboardAvoidingView>Provides a view that moves out of the way of the virtual keyboard automatically.
<Linking>Provides a general interface to interact with both incoming and outgoing app links.
<Modal>Provides a simple way to present content above an enclosing view.
<PixelRatio>Provides access to the device pixel density.
<RefreshControl>This component is used inside a ScrollView to add pull to refresh functionality.
<StatusBar>Component to control the app status bar.

Android and iOS

     Android and iOS also have some components that are specific to their devices. On iOS there is only one, the ActionSheetIOS. ActionSheetIOS displays the native Action Sheets component for iOS. It is a specific style of alert that appears in response to a control or action and gives the user two or more choices related to the current context. Android has a few components that are specific to their OS. BackHandler detects hardware button presses for back navigation. DrawerLayoutAndroid wraps the DrawerLayout platform that creates content that can be hidden or pulled in from the side. PermissionsAndroid provides access to the permissions model that allows the user to choose what permissions the app should have. Finally, ToastAndroid creates a toast alert notification.


CSS in React Native

     Since there is no true CSS in React Native, how do we style our apps? All React Native core components accept a style prop that you can write your styles inline, or import the StyleSheet method that allows you to create classes that . Both provide a JavaScript object of camelCased CSS properties as keys and values. There are also many frameworks out there like Styled Components that would allow you to write more vanilla style CSS. Styles are not inherited the way CSS is in a browser, only Text components within Text components are inherited. So, in most cases you have to specify for each component the styles you want. There are also no units for dimensions (px, em, vw, etc.), you simply don't include them in your styles. There can either be fixed width and height or you can use flex containers to dynamically fit the components. Flexbox is used to layout components and each type of component has its own set of styles that are able to be applied to it.

  <View style={styles.container}>
    <Text style={styles.title}>React Native</Text>
  </View>
);

const styles = StyleSheet.create({
  container: {
    flex: 1,
    padding: 24,
    backgroundColor: "#eaeaea"
  },
  title: {
    marginTop: 16,
    paddingVertical: 8,
    borderWidth: 4,
    borderColor: "#20232a",
    borderRadius: 6,
    backgroundColor: "#61dafb",
    color: "#20232a",
    textAlign: "center",
    fontSize: 30,
    fontWeight: "bold"
  }
});

View Component Styles

PropertyTypeDescription
backfaceVisibility'visible' or 'hidden'Determines if the backface of an element should be visible or hidden.
backgroundColorcolorSets the color of the background.
borderSideColorcolorThe color of whatever side of the border you specify, top, right, left, or bottom. Can just be borderColor to set all 4 sides.
borderSidePositionRadiusnumberThe corner radius of whatever side and position you specify. Sides are top, right, bottom, left. Positions are end, left, right, start. Can just be borderRadius to set all 4 corners.
borderSidePositionWidthnumberThe width of whatever side and position you specify. Sides are top, right, bottom, left. Positions are end, left, right, start. Can just be borderWidth to set width of all 4 borders.
borderStyle'solid', 'dotted', or 'dashed'Sets the style of the border.
elevationnumberAndroid only prop that adds a drop shadow and affects the z-index for any overlapping views.
opacitynumberSets the opacity of the component.

   <View
      style={{
        flexDirection: "row",
        height: 100,
        padding: 20
      }}
    >
    <View style={{styles.box}}>

    const styles = StyleSheet.create({
      box: {
        backgroundColor: 'blue',
        flex: 0.5
      }
});

Image Component Styles

Along with the all of the above props, the Image component adds the following possible properties and methods.

PropertyTypeDescription
accessiblebooleanIndicates whether the image is accessible.
accessibilityLabelstringThe text that is read by a screen reader on an accessible image.
blurRadiusnumberSets the blur amount of the image. iOS has to be more than 5.
capInsetsobject: {top: number, left: number, bottom: number, right: number}When an image is resized, the corners will stay fixed to the size set.
defaultSourcenumberA static image that is displayed while loading the image. Can be an object on iOS.
fadeDurationnumberSets the duration of the fade on an element. Android only, default is 300ms.
loadingIndicatorSourcearray[ImageSourcePropTypes, number]Similar to source, represents the resource used to render the loading indicator. Displayed until the image is ready.
onErrorfunctionGets invoked on load error with {nativeEvent: {error}}.
onLayoutfunctionGets invoked on mount and layout changes with {nativeEvent: {layout: {x, y, width, height}}}
onLoadfunctionGets invoked when load completes successfully.
onLoadEndfunctionGets invoked when load completes whether it succeeds or fails.
onLoadStartfunctionGets invoked when loading starts.
onPartialLoadfunctionGets invoked when the partial load is complete. Partial load is a
onProgressfunctionGets invoked on download progress with {nativeEvent: {layout: {x, y, width, height}}}
overflow'visible' or 'hidden'Determines if the overflow of an element should be visible or hidden.
overlayColorstringAndroid only property that if an image has rounded corners the overlay can be set to a solid color.
progressiveRenderingEnabledboolAndroid only. When true, enables progressive jpeg streaming.
resizeMethod'auto', 'resize', 'scale'Should be used if the image's dimensions differ from the image view's dimensions. Defaults to auto which uses heuristics to pick between resize and scale, resize should be used if image is much larger than the view, and scale should be used if the image is smaller than the view.
resizeMode'cover', 'contain', 'stretch', 'repeat', 'center'Determines how to resize the image. Cover maintains aspect ratio and scales evenly, contain fits the image inside element, stretch scales height and width independently, repeat allows the image to repeat to cover the frame, and center causes the image to center along both dimensions.
sourceImageSourcePropTypeThe source is either a remote or local file URL.
testIDstringUnique id to be used in testing scripts.
tintColorcolorChanges any non-transparent pixels to the tintColor.

Methods

getSize()Image.getSize(uri, success, [failure])Retrieve the width and height in pixels of an image before its displayed.
getSizeWithHeaders()Image.getSizeWithHeaders(uri, success, [failure])Retrieve the width and height in pixels of an image before its displayed with the ability to provide the headers for the request.
prefetch()Image.prefetch(url)Prefetches a remote image for later use by downloading it to the disk cache.
abortPrefetch()Image.abortPrefetch(requestId)Abort a prefetch request, android only.
queryCache()Image.queryCache(urls)Perform cace interrogation, returns a mapping from URL to cace status.
resolveAssetSource()Image.resolveAssetSource(source)Resolves an asset reference into an object with properties uri, width, height.

import React from 'react';
import { View, Image, StyleSheet } from 'react-native';

const styles = StyleSheet.create({
  container: {
    paddingTop: 50,
  },
  tinyLogo: {
    width: 50,
    height: 50,
  },
  logo: {
    width: 66,
    height: 58,
  },
});

const DisplayAnImage = () => {
  return (
    <View style={styles.container}>
      <Image
        style={styles.tinyLogo}
        source={require('@expo/snack-static/react-native-logo.png')}
      />
      <Image
        style={styles.tinyLogo}
        source={{
          uri: 'https://reactnative.dev/img/tiny_logo.png',
        }}
      />
      <Image
        style={styles.logo}
        source={{
          uri:
            'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADMAAAAzCAYAAAA6oTAqAAAAEXRFWHRTb2Z0d2FyZQBwbmdjcnVzaEB1SfMAAABQSURBVGje7dSxCQBACARB+2/ab8BEeQNhFi6WSYzYLYudDQYGBgYGBgYGBgYGBgYGBgZmcvDqYGBgmhivGQYGBgYGBgYGBgYGBgYGBgbmQw+P/eMrC5UTVAAAAABJRU5ErkJggg==',
        }}
      />
    </View>
  );
}

export default DisplayAnImage;

Text Component Styles

PropertyTypeDescription
colorcolorSets the color of the text.
fontFamilystringSets the font family of the text.
fontSizenumberSets the size of the text.
fontStyle'normal', 'italic'Sets the style of the text.
fontVariant'small-caps', 'oldstyle-nums', lining-nums', 'tabular-numbs', 'proportional-nums'Sets the variant of the text on iOS only.
fontWeightnumber, 'normal', 'bold'Sets how bold the text is.
includeFontPaddingboolFalse removes extra font padding, default is true.
letterSpacingnumberIncrease or decrease the space between characters in the text.
lineHeightnumberSets the position of the text along the vertical axis.
suppressHighlightingboolWhen true, no changes are made to the text. By default, a gray oval highlights the text on press down.
testIDstringUnique identifier used in testing.
textAlign'auto', 'left', 'right', 'center', 'justify'Sets the position of the text on the all axises.
textAlignVertical'auto', 'top', 'bottom', 'center'Sets the position of the text on the vertical axis.
textBreakStrategy'simple', 'highQuality', 'balanced'Android only, sets the way the text breaks. Default is highQuality.
textDecorationColorcoloriOS only, sets the color of the text decoration.
textDecorationLine'none', 'underline', 'line-through', 'underline line-through'Sets the style of the text decoration.
textDecorationStyle'solid', 'double', 'dotted', 'dashed'iOS only, sets the style of the text.
textShadowColorcolorSets the color of the text shadow.
textShadowOffsetobject: {width: number, height: number}Sets the offset of the text shadow.
textShadowRadiusnumberSets the blur radius of the text shadow.
textTransform'none', 'uppercase', 'lowercase', 'capitalize'Sets the way to transform the text.
writingDirection'auto', 'ltr', 'rtl'iOS only, sets the direction of the text.


const TextInANest = () => {
  const titleText = useState("Bird's Nest");
  const bodyText = useState("This is not really a bird nest.");

  return (
    <Text style={styles.baseText}>
      <Text style={styles.titleText} onPress={onPressTitle}>
        {titleText}
        {"\n"}
        {"\n"}
      </Text>
      <Text numberOfLines={5}>{bodyText}</Text>
    </Text>
  );
};

const styles = StyleSheet.create({
  baseText: {
    fontFamily: "Cochin"
  },
  titleText: {
    fontSize: 20,
    fontWeight: "bold"
  }
});

Button

     Buttons in React Native have a very limited amount of properties that can be applied to them. They cannot have a direct style prop on a button and it is a self-closing tag. Text is set with the title prop and color can be set, otherwise you can use TouchableOpacity or TouchableNativeFeedback to build your own button. You can also surround a Button with a View container to create a larger margin.

PropertyTypeDescription
accessibilityLabelstringSets the text that is read by the screen reader when the button is hovered or clicked on.
colorcolorSets the color of the button.
disabledboolIf true, the button has no interactions. Default is false.
hasTVPreferredFocusboolApple TV only, to check if tv is the preferred focus.
nextFocusDirectionnumberAndroid only, defines the next view that gets focused. Directions are Down, Forward, Up, Left, and Right
onPressfunctionProvides the function that should be executed when the button is pressed.
testIDstringUnique identifier for testing.
titlestringSets the text that appears on the button.
touchSoundDisabledboolAndroid only, tell system not to play a sound on touch.

<Button
  onPress={onPressLearnMore}
  title="Learn More"
  color="#841584"
  accessibilityLabel="Learn more about this purple button"
/>

Transforms

     Transforms are style properties that will modify the appearance of an element.

<View style={[styles.box, {
        transform: [
          { rotateX: "45deg" },
          { rotateZ: "45deg" }
        ]
      }]}>