Styling in React Native- A Step By Step Guide

Styling in React Native- A Step By Step Guide

In this article, we are going to cover the basics of app styling and design in a step by step manner.

It can be hard to understand exactly why clients pay so much for design work. After all, as long as you have a functional app, it can’t matter that much what it looks like, right?

Unfortunately, this simply isn’t the case. Styling is one of the most important aspects of your online presence. This doesn’t necessarily mean you need to pay an exorbitant amount of money for top-tier designers, but rather that you need to find a style that works for your business.

When it comes to React Native, styling becomes little more tricky as the dynamics of styling for React and React Native are totally opposite. It becomes more brutal if you are coming from a backend domain. In this article, we are going to cover the basics of app styling and design in a step by step manner. I might go for a series depending on the response. Let’s begin with following for now:

  1. StyleSheet in React Native
  2. FlexBox in React Native
  3. Handling Images in React Native
  4. Custom Fonts in React Native
  5. Positioning container and elements in React native

StyleSheet in React Native

A StyleSheet is an abstraction similar to CSS StyleSheets. There can be many ways to create styles for your component. Some developers prefer adding it to the bottom of each file while some go for a separate to style all the components at one place. By moving styles away from the render function, you’re making the code easier to understand. Here is the code to use StyleSheet in react native.

import { StyleSheet } from “react-native”;
const styles = StyleSheet.create({
  container: {     
    flex: 1,
  },   
  title: {
    fontSize: 24,     
    fontWeight: 'bold',  
  },   
});

No matter which option you choose. The declaration of StyleSheet remains the same for both the approaches.

Inline Styling: Like CSS we can also provide inline styling in React Native.

<Text style={{fontSize: 24,color: "#fff"}}>Random Text</Text>

//styling with class styles and inline styles
<Text style={[styles.title,{fontSize: 24,color: "#fff"}]}>
  Random Text
</Text>

Naming:

Naming the styles is a good way to add meaning to the low-level components in the render function. No units such as px, pt or rem are used in React Native. The values are based on screen size.

//It is advised that the styles are named using camel case
flexWrap: "wrap",
fontWeight: "900",
width: 200 | "100%",
height: 300 | "100%",
// There is no unit in react native you can use either of these to adjust styling.
paddingVertical: 30,
paddingHorizontal: 20,

Reusability:

Now reusability depends totally on experience, the more predictable and forecasting is your code more are the chances of reusing the same style for different case scenario in the app or a website. When you are dealing with reusable styling to minimize the code length, always opt for styling which is not component specific and global in nature. You can easily assign the custom values dynamically which adds the freedom to customize the component at the run time and reduces the stress of predictability. color, size, weight, margin, and padding all this should be provided at the run time and should be assigned variable values during styling.

Color codes:

Colors in react native is similar to the CSS styling. We can use both hexadecimal and functional notation:

//All these will give you color black
color: "#000"
color: "black"
color: "rgba(0,0,0,0)"
color: "rgb(0,0,0)"

Learn more about colors and color codes here.

In react native, you can create color variables like this so that if you want to change the color in future you can do by changing it at only one place.

export const colors = {
  white: '#fff',
  black: '#000',
  brand: "#c6bc9d",
}
// importing in the styles file like this
import {colors} from "./colors";
export const styles = StyleSheet.create({
container: {
  flex: 1,
  backgroundColor: colors.brand,
},

Components in React Native

  1. View: The most fundamental component for building a UI, View is a container that supports layout with flexbox, style, some touch handling, and accessibility controls. View maps directly to the native view equivalent on whatever platform React Native is running on, whether that is a UIView, <div>, android.view, etc.
<View style={styles.container}>
 <View style={styles.inline}>
  <Text style={styles.date}>READ MORE</Text>
  <Text style={styles.date}> Date is </Text>
 </View>
  <Text style={styles.text}>{data.item.title}</Text>
 </View>
</View>
//There should always be a parent in React Native if there are more than one View in the render function.
//Major Styling properties for View are as follow: 
borderWidth: 4,
borderWidthColor: "red",
borderRightWidth: 4,
borderLeftWidth: 4,
borderTopWidth: 4,
borderBottomWidth: 4,
paddingVertical: 3,
paddingHorizontal: 3
zIndex: 100
// Shadow color in View
shadowColor: "red"
shadowOffset: "{width:3,height: 3}"
shadowOpacity: 3,
shadowRadius: 4

  1. Text: A React component for displaying text.
<Text style={styles.baseText}>
 <Text style={styles.titleText} Random Text</Text>
 <Text numberOfLines={5}>
   {this.state.titleText}{'\n'}{'\n'}
 </Text>
</Text>
//Some major Text properties are as follows: 
fontSize: 30,
textAlign: "center" | "justify" | "left" | "right",
color: "red",
fontStyle: "normal" | "italic,
textDecoration: "underline" | "none" | "line-through"
fontFamily: "Roboto",
letterSpacing: 5,
textDecorationColor: "#fff",

FlexBox in React Native

If you are aware of Flexbox in CSS. Flex is not going to be a trouble and if you don’t I advise going through this link. Some important properties are as follows:

Flex Direction: Default property is a column as in an app the view is basically scrolling on the Y-axis i.e Vertical (top to bottom) and not sidewise i.e Horizontal (left to right). So if you want to scroll across horizontally you can use flexDirection: “row”.

Justify Content: You can basically use the main options which are flex-start,flex-end,space-between,space-around, center.

  1. justify-content: “center”= aligns every child in the center.
  2. justify-content: “flex-end” = aligns every child to the end.
  3. justify-content: “flex-start”= aligns every child to the end.
  4. justify-content: “space-around” =aligns every child with equal spacing with each other.
  5. justify-content: “space-between” =aligns every child with equal spacing with each other. But the first and last child would be at the corners either top or bottom or left or right.
  6. Justify Content works for both row and column view. You can opt for styling using flex to avoid unwanted calculations of padding and margin.

**Align items: **It determines the alignment of children along the **secondary axis. **If the primary axis is a row, then the secondary is a **column **and vice versa. Just like justify content we have few options which are flex-start,flex-end, center, stretch.

**Flex wrap: **It will work as flex-wrap in CSS. For example, if we have so many numbers of boxes and we did not mention flexWrap: ‘wrap’ property to them, then all the boxes render in the parent but we only see the number of boxes fit on the screen, not all the boxes. The default value for flexWrap is nowrap.

<strong>flexWrap: ‘wrap’ | ‘nowrap’</strong>

Handling Images in React Native

React Native provides a unified way of managing images and other media assets in your iOS and Android apps. To add a static image to your app, place it somewhere in your source code tree and reference it like this:

<Image source={require('./my-icon.png')} />

This freedom to use the images in the app in any format .png or .jpg is an asset which is not provided for the native app languages. You can also use Url for getting the image source.

<Image source={{uri: 'app_icon'}} style={{width: 40, height: 40}} />

You can learn more about the images here. When it comes to styling the images based on design. It is advised not to give a custom width and height to the images as it may alter view in various devices. However, we have a property resizeMode which can be used to align the image in a view. The syntax is as follows

resizeMode: 'contain'
resizeMode: 'conver'
resizeMode: 'center'
resizeMode: 'stretch'

when an image in inside a view of particular width and height. You can use any of the above property to align the image with the parent div.

contain: It uses the original width and height of the image and aligns it within the parent div.

cover: It basically fills the whole view with the image not basically advised as it might cut some parts from the image in order to adjust the whole view.

center: It aligns the image to the center of the parent view i.e it makes the image of literally very small size using padding and assigns it to the center of the parent view.

stretch: As the name suggests it stretches the image and aligns it within the parent view. *Not advised as it alters image quality.

Image Background: A common feature request from developers familiar with the web is background-image. To handle this use case, you can use the <ImageBackground> component.

<ImageBackground 
  source={...} 
  style={{width: '100%', height: '100%'}}
>     
  <Text>Inside</Text>
</ImageBackground>

**Dynamic handling of images: **In case there is a scenario in which you want to show two different images based on any condition. You can easily manage the code like this.

var icon = this.props.active ? require('./my-icon-active.png'):  require('./my-icon-inactive.png');
 
<Image source={icon} />;

If you are using API to handle the image URL then

renderItem=(movies)=>
<TouchableOpacity style={styles.list}
   onPress={()=>this.openModal(movies.item)}>
  <Image style={styles.img} source={{uri: movies.item.poster}} /></TouchableOpacity>

Custom Fonts in React Native

We can use custom fonts in React Native. You can add your custom fonts by the following steps:

  1. Add fonts folder to asset library:

2. Package.json: add rnpm to package.json providing the path to the font files:

"rnpm": {    "assets": [ "./assets/fonts/"    ]},

  1. React Native link command to link it to font files
react-native link

  1. Once the terminal shows that the fonts have been linked you can use it like this in the styling
title: {
  fontFamily: "Roboto",
  fontSize: 30,
  textAlign: "center",
},

Positioning container and elements in React native

Position in React Native is similar to regular CSS, but everything is set to relative by default, so absolute positioning is always just relative to the parent. If you want to position a child using specific numbers of logical pixels relative to its parent, set the child to have an absolute position. If you want to position a child relative to something that is not its parent, just don't use styles for that. Use the component tree. See https://github.com/facebook/css-layout for more details on how position differs between React Native and CSS.

const styles = StyleSheet.create({
container:{
  backgroundColor: colors.red,
  flex: 1,
  position: "relative",
},
//relative parent for whole screen
close:{
  position: "fixed",
  top: 50,
  right: 20,
  zIndex: 100
},
//positions the close icon at the top-right of the screen
menu:{
  position: "absolute,
  bottom: 0,
  left: 0,
  width: "100%"
},
//positions the menu at the bottom of the screen
})

Conclusion:

Styling and design are a very vast concept and cannot be covered in one article. There might be some scenario when you are struck with some design or component and are unable to style it as per need. Feel free to let me know via my email or website and I would love to help you with solving them. Also, let me know If there is anything missing or needs amendment. Together we will make this world a better and beautiful place.

React Native Map components for iOS + Android

React Native Map components for iOS + Android

React Native Map components for iOS + Android.Contribute to react-native-community/react-native-maps development by creating an account on GitHub

React Native Map components for iOS + Android

Installation

See Installation Instructions.

See Setup Instructions for the Included Example Project.

Compatibility

Due to the rapid changes being made in the React Native ecosystem, we are not officially going to support this module on anything but the latest version of React Native. With that said, we will do our best to stay compatible with older versions as much that is practical, and the peer dependency of this requirement is set to "react-native": "*" explicitly for this reason. If you are using an older version of React Native with this module though, some features may be buggy.

Note about React requires

Since react-native 0.25.0, React should be required from node_modules. React Native versions from 0.18 should be working out of the box, for lower versions you should add react as a dependency in your package.json.

General Usage
source-js
import MapView from 'react-native-maps';

or

source-js
var MapView = require('react-native-maps');

This MapView component is built so that features on the map (such as Markers, Polygons, etc.) are specified as children of the MapView itself. This provides an intuitive and react-like API for declaratively controlling features on the map.

Rendering a Map with an initial region

MapView
source-js-jsx
  <MapView
    initialRegion={{
      latitude: 37.78825,
      longitude: -122.4324,
      latitudeDelta: 0.0922,
      longitudeDelta: 0.0421,
    }}
  />

Using a MapView while controlling the region as state

source-js-jsx
getInitialState() {
  return {
    region: {
      latitude: 37.78825,
      longitude: -122.4324,
      latitudeDelta: 0.0922,
      longitudeDelta: 0.0421,
    },
  };
}

onRegionChange(region) {
  this.setState({ region });
}

render() {
  return (
    <MapView
      region={this.state.region}
      onRegionChange={this.onRegionChange}
    />
  );
}

Rendering a list of markers on a map

source-js-jsx
import { Marker } from 'react-native-maps';

<MapView
  region={this.state.region}
  onRegionChange={this.onRegionChange}
>
  {this.state.markers.map(marker => (
    <Marker
      coordinate={marker.latlng}
      title={marker.title}
      description={marker.description}
    />
  ))}
</MapView>

Rendering a Marker with a custom view

source-js-jsx
<Marker coordinate={marker.latlng}>
  <MyCustomMarkerView {...marker} />
</Marker>

Rendering a Marker with a custom image

source-js-jsx
<Marker
  coordinate={marker.latlng}
  image={require('../assets/pin.png')}
/>

Rendering a custom Marker with a custom Callout

source-js-jsx
import { Callout } from 'react-native-maps';

<Marker coordinate={marker.latlng}>
  <MyCustomMarkerView {...marker} />
  <Callout>
    <MyCustomCalloutView {...marker} />
  </Callout>
</Marker>

Draggable Markers

source-js-jsx
<MapView initialRegion={...}>
  <Marker draggable
    coordinate={this.state.x}
    onDragEnd={(e) => this.setState({ x: e.nativeEvent.coordinate })}
  />
</MapView>

Using a custom Tile Overlay

Tile Overlay using tile server

source-js-jsx
import { UrlTile } from 'react-native-maps';

<MapView
  region={this.state.region}
  onRegionChange={this.onRegionChange}
>
  <UrlTile
    /**
     * The url template of the tile server. The patterns {x} {y} {z} will be replaced at runtime
     * For example, http://c.tile.openstreetmap.org/{z}/{x}/{y}.png
     */
    urlTemplate={this.state.urlTemplate}
    /**
     * The maximum zoom level for this tile overlay. Corresponds to the maximumZ setting in
     * MKTileOverlay. iOS only.
     */
    maximumZ={19}
    /**
     * flipY allows tiles with inverted y coordinates (origin at bottom left of map)
     * to be used. Its default value is false.
     */
    flipY={false}
  />
</MapView>

For Android: add the following line in your AndroidManifest.xml

text-xml
<uses-permission android:name="android.permission.INTERNET" />

For IOS: configure App Transport Security in your app

Tile Overlay using local tiles

Tiles can be stored locally within device using xyz tiling scheme and displayed as tile overlay as well. This is usefull especially for offline map usage when tiles are available for selected map region within device storage.

source-js-jsx
import { LocalTile } from 'react-native-maps';

<MapView
  region={this.state.region}
  onRegionChange={this.onRegionChange}
>
  <LocalTile
   /**
    * The path template of the locally stored tiles. The patterns {x} {y} {z} will be replaced at runtime
    * For example, /storage/emulated/0/mytiles/{z}/{x}/{y}.png
    */
   pathTemplate={this.state.pathTemplate}
   /**
    * The size of provided local tiles (usually 256 or 512).
    */
   tileSize={256}
  />
</MapView>

For Android: LocalTile is still just overlay over original map tiles. It means that if device is online, underlying tiles will be still downloaded. If original tiles download/display is not desirable set mapType to 'none'. For example:

<MapView
  mapType={Platform.OS == "android" ? "none" : "standard"}
>

See OSM Wiki for how to download tiles for offline usage.

Overlaying other components on the map

Place components you that wish to overlay MapView underneath the MapView closing tag. Absolutely position these elements.

source-js-jsx
render() {
  return (
    <MapView
      region={this.state.region}
    />
    <OverlayComponent
      style={{position: “absolute”, bottom: 50}}
    />
  );
}

Customizing the map style

Create the json object, or download a generated one from the google style generator.

source-js-jsx
// The generated json object
mapStyle = [ ... ]

render() {
  return (
    <MapView
      region={this.state.region}
      onRegionChange={this.onRegionChange}
      customMapStyle={mapStyle}
    />
  );
}

For iOS, in addition to providing the mapStyle you will need to do the following

source-js-jsx
import MapView, { PROVIDER_GOOGLE } from 'react-native-maps'

// ...

<MapView
  provider={PROVIDER_GOOGLE}
  customMapStyle={MapStyle}
>

Then add the AirGoogleMaps directory:

https://github.com/react-native-community/react-native-maps/blob/1e71a21f39e7b88554852951f773c731c94680c9/docs/installation.md#ios

An unofficial step-by-step guide is also available at https://gist.github.com/heron2014/e60fa003e9b117ce80d56bb1d5bfe9e0

Examples

To run examples:

source-shell
npm i
npm start

#Android
npm run run:android

#iOS
npm run build:ios
npm run run:ios

MapView Events

The <MapView /> component and its child components have several events that you can subscribe to. This example displays some of them in a log as a demonstration.

Tracking Region / Location

Programmatically Changing Region

One can change the mapview's position using refs and component methods, or by passing in an updated region prop. The component methods will allow one to animate to a given position like the native API could.

Changing the style of the map

Arbitrary React Views as Markers

Using the MapView with the Animated API

The <MapView /> component can be made to work with the Animated API, having the entire region prop be declared as an animated value. This allows one to animate the zoom and position of the MapView along with other gestures, giving a nice feel.

Further, Marker views can use the animated API to enhance the effect.

Issue: Since android needs to render its marker views as a bitmap, the animations APIs may not be compatible with the Marker views. Not sure if this can be worked around yet or not.

Markers' coordinates can also be animated, as shown in this example:

Polygon Creator

Other Overlays

So far, <Circle />, <Polygon />, and <Polyline /> are available to pass in as children to the <MapView /> component.

Gradient Polylines (iOS MapKit only)

Gradient polylines can be created using the strokeColors prop of the <Polyline> component.

Default Markers

Default markers will be rendered unless a custom marker is specified. One can optionally adjust the color of the default marker by using the pinColor prop.

Custom Callouts

Callouts to markers can be completely arbitrary react views, similar to markers. As a result, they can be interacted with like any other view.

Additionally, you can fall back to the standard behavior of just having a title/description through the <Marker />'s title and description props.

Custom callout views can be the entire tooltip bubble, or just the content inside of the system default bubble.

To handle press on specific subview of callout use <CalloutSubview /> with onPress. See Callouts.js example.

Image-based Markers

Markers can be customized by just using images, and specified using the image prop.

Draggable Markers

Markers are draggable, and emit continuous drag events to update other UI during drags.

Lite Mode ( Android )

Enable lite mode on Android with liteMode prop. Ideal when having multiple maps in a View or ScrollView.

On Poi Click (Google Maps Only)

Poi are clickable, you can catch the event to get its information (usually to get the full detail from Google Place using the placeId).

Animated Region

The MapView can accept an AnimatedRegion value as its region prop. This allows you to utilize the Animated API to control the map's center and zoom.

source-js-jsx
import MapView, { AnimatedRegion, Animated } from 'react-native-maps';

getInitialState() {
  return {
    region: new AnimatedRegion({
      latitude: LATITUDE,
      longitude: LONGITUDE,
      latitudeDelta: LATITUDE_DELTA,
      longitudeDelta: LONGITUDE_DELTA,
    }),
  };
}

onRegionChange(region) {
  this.state.region.setValue(region);
}

render() {
  return (
    <Animated
      region={this.state.region}
      onRegionChange={this.onRegionChange}
    />
  );
}

Animated Marker Position

Markers can also accept an AnimatedRegion value as a coordinate.

source-js-jsx
import Mapview, { AnimatedRegion, Marker } from 'react-native-maps';

getInitialState() {
  return {
    coordinate: new AnimatedRegion({
      latitude: LATITUDE,
      longitude: LONGITUDE,
    }),
  };
}

componentWillReceiveProps(nextProps) {
  const duration = 500

  if (this.props.coordinate !== nextProps.coordinate) {
    if (Platform.OS === 'android') {
      if (this.marker) {
        this.marker._component.animateMarkerToCoordinate(
          nextProps.coordinate,
          duration
        );
      }
    } else {
      this.state.coordinate.timing({
        ...nextProps.coordinate,
        duration
      }).start();
    }
  }
}

render() {
  return (
    <MapView initialRegion={...}>
      <MapView.Marker.Animated
        ref={marker => { this.marker = marker }}
        coordinate={this.state.coordinate}
      />
    </MapView>
  );
}

If you need a smoother animation to move the marker on Android, you can modify the previous example:

source-js-jsx
// ...

componentWillReceiveProps(nextProps) {
  const duration = 500

  if (this.props.coordinate !== nextProps.coordinate) {
    if (Platform.OS === 'android') {
      if (this.marker) {
        this.marker._component.animateMarkerToCoordinate(
          nextProps.coordinate,
          duration
        );
      }
    } else {
      this.state.coordinate.timing({
        ...nextProps.coordinate,
        duration
      }).start();
    }
  }
}

render() {
  return (
    <MapView initialRegion={...}>
      <Marker.Animated
        ref={marker => { this.marker = marker }}
        coordinate={this.state.coordinate}
      />
    </MapView>
  );
}

Take Snapshot of map

source-js-jsx
import MapView, { Marker } from 'react-native-maps';

getInitialState() {
  return {
    coordinate: {
      latitude: LATITUDE,
      longitude: LONGITUDE,
    },
  };
}

takeSnapshot () {
  // 'takeSnapshot' takes a config object with the
  // following options
  const snapshot = this.map.takeSnapshot({
    width: 300,      // optional, when omitted the view-width is used
    height: 300,     // optional, when omitted the view-height is used
    region: {..},    // iOS only, optional region to render
    format: 'png',   // image formats: 'png', 'jpg' (default: 'png')
    quality: 0.8,    // image quality: 0..1 (only relevant for jpg, default: 1)
    result: 'file'   // result types: 'file', 'base64' (default: 'file')
  });
  snapshot.then((uri) => {
    this.setState({ mapSnapshot: uri });
  });
}

render() {
  return (
    <View>
      <MapView initialRegion={...} ref={map => { this.map = map }}>
        <Marker coordinate={this.state.coordinate} />
      </MapView>
      <Image source={{ uri: this.state.mapSnapshot.uri }} />
      <TouchableOpacity onPress={this.takeSnapshot}>
        Take Snapshot
      </TouchableOpacity>
    </View>
  );
}

Zoom to Specified Markers

Pass an array of marker identifiers to have the map re-focus.

Zoom to Specified Coordinates

Pass an array of coordinates to focus a map region on said coordinates.

Troubleshooting

My map is blank

  • Make sure that you have properly installed react-native-maps.
  • Check in the logs if there is more informations about the issue.
  • Try setting the style of the MapView to an absolute position with top, left, right and bottom values set.
  • Make sure you have enabled Google Maps API in Google developer console
source-js
const styles = StyleSheet.create({
  map: {
    ...StyleSheet.absoluteFillObject,
  },
});
source-js-jsx
<MapView
  style={styles.map}
  // other props
/>

Inputs don't focus

  • When inputs don't focus or elements don't respond to tap, look at the order of the view hierarchy, sometimes the issue could be due to ordering of rendered components, prefer putting MapView as the first component.

Bad:

source-js-jsx
<View>
  <TextInput/>
  <MapView/>
</View>

Good:

source-js-jsx
<View>
  <MapView/>
  <TextInput/>
</View>

How to build a news app with JavaScript and React Native

How to build a news app with JavaScript and React Native

How to build a news app with JavaScript and React Native

Requirements for building the app:

  • A basic understanding of the JavaScript language.
  • Node.js, and react native.
  • Libraries used: moment, react-native, react-native-elements.

If you’re not familiar with these resources, don’t worry — they are quite easy to use.

The topics we will cover in the post are:

  • A basic understanding of the JavaScript language.
  • Node.js, and react native.
  • Libraries used: moment, react-native, react-native-elements.

And more…so let’s get started!

You can find the full project repo HERE.

News API

A simple and easy-to-use API that returns JSON metadata for headlines and articles live all over the web right now. — NewsAPI.org
First, you should go ahead and sign up for News Api to get your free apiKey (your authentication key).

Create a new React Native project, and call it news_app (or whatever you want). In the project directory, make a new folder and call it src . In srccreate a folder an name it components . So your project directory should look something like this:

In the src folder, create a new file called news.js . In this file we are going to fetch the JSON that contains the headlines from the News API.

news.js
const url =
  "https://newsapi.org/v2/top-headlines?country=us&apiKey=YOUR_API_KEY_HERE";

export async function getNews() {
  let result = await fetch(url).then(response => response.json());
  return result.articles;
}

Make sure you replace YOUR_API_KEY_HERE with your own API key. For more information about the News API, go to newsapi docs.

Now we declare the getNews function, which is going to fetch the articles for us. Export the function so we can use it in our App.js file.

App.js
import React from 'react';
import { FlatList } from 'react-native';

// Import getNews function from news.js
import { getNews } from './src/news';
// We'll get to this one later
import Article from './src/components/Article';

export default class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = { articles: [], refreshing: true };
    this.fetchNews = this.fetchNews.bind(this);
  }
  // Called after a component is mounted
  componentDidMount() {
    this.fetchNews();
   }

  fetchNews() {
    getNews()
      .then(articles => this.setState({ articles, refreshing: false }))
      .catch(() => this.setState({ refreshing: false }));
  }

  handleRefresh() {
    this.setState(
      {
        refreshing: true
    },
      () => this.fetchNews()
    );
  }

  render() {
    return (
      <FlatList
        data={this.state.articles}
        renderItem={({ item }) => <Article article={item} />}
        keyExtractor={item => item.url}
        refreshing={this.state.refreshing}
        onRefresh={this.handleRefresh.bind(this)}
      />
  );
  }
}

In the constructor, we define the initial state. articles will store our articles after we fetch them, and refreshing will help us in refresh animation. Notice that I setrefreshing to true, because when we start the app, we want the animation to start while we load the articles.

componentDidMount is invoked immediately after a component is mounted. Inside it we call the fetchNews method.

componentDidMount() {
  this.fetchNews();
}

In fetchNews we call getNews() which returns a promise. So we use the .then() method which takes a callback function, and the callback function takes an argument (the articles).

Now assign the articles in the state to the articles argument. I only typed articles because it’s a new ES6 syntax that means { articles: articles } , and we set refreshing to false to stop the spinner animation.

fetchNews() {
  getNews().then(
      articles => this.setState({ articles, refreshing: false })
  ).catch(() => this.setState({ refreshing: false }));
}

.catch() is called in rejected cases.

handleRefresh starts the spinner animation and call fetchNews(). We pass () => this.fetchNews() , so it’s called immediately after we assign the state.

handleRefresh() {
  this.setState({ refreshing: true },() => this.fetchNews());
}

In the render method, we return a FlatList element. Then we pass some props. data is the array of articles from this.state. The renderItem takes a function to render each item in the array, but in our case it just returns theArticle component we imported earlier (we’ll get there). And we pass the article item as a prop to use later in that component.

Article.js

In src/components create a new JavaScript file and call it Article.js.

Let’s start by installing two simple libraries using npm: react-native-elements, which gives us some premade components we could use, and moment that will handle our time.

run using terminal/cmd:

npm install --save react-native-elements moment

In Article.js:

import React from 'react';
import { View, Linking, TouchableNativeFeedback } from 'react-native';
import { Text, Button, Card, Divider } from 'react-native-elements';
import moment from 'moment';

export default class Article extends React.Component {
  render() {
    const {
      title,
      description,
      publishedAt,
      source,
      urlToImage,
      url
    } = this.props.article;
    const { noteStyle, featuredTitleStyle } = styles;
    const time = moment(publishedAt || moment.now()).fromNow();
    const defaultImg =
      'https://wallpaper.wiki/wp-content/uploads/2017/04/wallpaper.wiki-Images-HD-Diamond-Pattern-PIC-WPB009691.jpg';

    return (
      <TouchableNativeFeedback
        useForeground
        onPress={() => Linking.openURL(url)}
      >
        <Card
          featuredTitle={title}
          featuredTitleStyle={featuredTitleStyle}
          image={{
            uri: urlToImage || defaultImg
          }}
        >
          <Text style={{ marginBottom: 10 }}>
            {description || 'Read More..'}
          </Text>
          <Divider style={{ backgroundColor: '#dfe6e9' }} />
          <View
            style={{ flexDirection: 'row', justifyContent: 'space-between' }}
          >
            <Text style={noteStyle}>{source.name.toUpperCase()}</Text>
            <Text style={noteStyle}>{time}</Text>
          </View>
        </Card>
      </TouchableNativeFeedback>
    );
  }
}

const styles = {
  noteStyle: {
    margin: 5,
    fontStyle: 'italic',
    color: '#b2bec3',
    fontSize: 10
  },
  featuredTitleStyle: {
    marginHorizontal: 5,
    textShadowColor: '#00000f',
    textShadowOffset: { width: 3, height: 3 },
    textShadowRadius: 3
  }
};

There is a lot going on here. First, we start by destructuring the articleprop and the styles object defined below the class.

In render we define time to store the time for when the article was published. We use the moment library to convert the date to the time passed since then, and we pass publishedAt or time from now if publishedAt is null.

defaultImg is assigned an image URL in case the URL of the article image is null.

The render method returns TouchableNativeFeedback (use TouchableOpacityinstead if it does not work on your platform) to handle when the user presses the card. We pass it some props: useForground which tells the element to use the foreground when displaying the ripple effect on the card, and onPress , which takes a function and executes it when the user presses the card. We passed () => Linking.openUrl(url) which simply opens the URL to the full article when we press the card.

The card takes three props: featuredTitle which is just a fancy title placed over the image you could use title instead if you want, featuredTitleStyle to style it, and image which is the article image from the article prop. Otherwise, if its null , it’s going to be the defaultImg.

..
  featuredTitle={title}
  featuredTitleStyle={featuredTitleStyle}
  image={{ uri: urlToImage || defaultImg }}
..

As for the text element, it will hold the description for the article.

<Text style={{ marginBottom: 10 }}>{description}

We added a divider to separate the description from time and source name.

<Divider style={{ backgroundColor: '#dfe6e9' }} />

Below the Divider , we have a View that contains the source name and the time the article was published.

..
<View 
  style={{ flexDirection: ‘row’, justifyContent: ‘space-between’ }} > 
  <Text style={noteStyle}>{source.name.toUpperCase()}</Text>
  <Text style={noteStyle}>{time}</Text>
</View>
..

After the class, we defined the styles for these components.

Now if we run the app:

There you go! The source code for the app is available on GitHub HERE you can improve upon it and make a pull request😄.

React Native Maps Tutorial | Add Google Maps to iOS & Android Apps

React Native Maps Tutorial | Add Google Maps to iOS & Android Apps

In this react native tutorial, you'll learn to integrate Google maps to your react native app using react-native-maps package. It is a complete step by step guide to add Google maps to your iOS & Android apps developed by react native

In this react native tutorial, you'll learn to integrate Google maps to your react native app using react-native-maps package. It is a complete step by step guide to add Google maps to your iOS & Android apps developed by react native. Here I have shown you a manual installation process without expo.

React Native Maps Package GitHub link https://github.com/react-native-community/react-native-maps