Introduction
Here, I am going to explain how we can create a simple list using React-Native so that it will work in both iOS and Android applications. I have already given a basic introduction about react-native, those who want to check can
click here. In this article, I will be explaining how to fetch data from API and show the results in a List (RecyclerView in Android, UITableView in iOS). Please go through the introductory article for the initial setups.
First, create the project using the following command,
- react native init <projectName>
- react-native init ListSample
This will create the project, which will contain Android and iOS folders.
Open the App.js file which will be an entry point of React-Native applications. This file will contain-
- import React, {
- Component
- } from 'react';
- import {
- Platform,
- StyleSheet,
- Text,
- View
- } from 'react-native';
- const instructions = Platform.select({
- ios: 'Press Cmd+R to reload,\n' + 'Cmd+D or shake for dev menu',
- android: 'Double tap R on your keyboard to reload,\n' + 'Shake or press menu button for dev menu',
- });
- type Props = {};
- exportdefaultclass App extends Component < Props > {
- render() {
- return ( < View style = {
- styles.container
- } > < Text style = {
- styles.welcome
- } > Hello World < /Text> < /View > );
- }
- }
- const styles = StyleSheet.create({
- container: {
- flex: 1,
- justifyContent: 'center',
- alignItems: 'center',
- backgroundColor: '#F5FCFF',
- },
- welcome: {
- fontSize: 20,
- textAlign: 'center',
- margin: 10,
- },
- instructions: {
- textAlign: 'center',
- color: '#333333',
- marginBottom: 5,
- },
- });
Delete the entire thing, we really don't need to import the header files,
- importReact, {Component} from'react';
- import { StyleSheet, Text, View,FlatList,TouchableOpacity,ActivityIndicator} from'react-native';
FaltList is similar to Android recyclerview; it shows a similar kind of data as an ActivityIndicator list. It is also the same in Android, which will show an indefinite progress bar while we are fetching data from API TouchableOpacity. It will be the new component which will make a view as touchable.
Here, I am taking the same API which is mentioned in the official documentation of react-native
https://facebook.github.io/react-native/movies.json
This will return a JSON like,
- {
- "title": "The Basics - Networking",
- "description": "Your app fetched this from a remote endpoint!",
- "movies": [{
- "id": "1",
- "title": "Star Wars",
- "releaseYear": "1977"
- }, {
- "id": "2",
- "title": "Back to the Future",
- "releaseYear": "1985"
- }, {
- "id": "3",
- "title": "The Matrix",
- "releaseYear": "1999"
- }, {
- "id": "4",
- "title": "Inception",
- "releaseYear": "2010"
- }, {
- "id": "5",
- "title": "Interstellar",
- "releaseYear": "2014"
- }]
- }
First, we need to fetch the data from API and then show the movies object as a list.
For this, there is a method named.
Which is a life cycle method and it will get executed after the render() method. From the official documentation, the life-cycle methods of a react-native application are as follows-
In the constructor, we will initialize a variable isLoading as true to the state. So the constructor will look like-
- constructor(props) {
- super(props);
- this.state = {
- isLoading: true
- }
- }
As per the documentation after the constructor, the render method will get executed. So in render(), we will check whether the isLoading is true. If true then we will show the Activity indicator on the UI, so that the user will be aware that there are some operations happening in the App.
- render() {
- if (this.state.isLoading) {
- return ( < Viewstyle = {
- {
- flex: 1,
- padding: 20
- }
- } > < Textstyle = {
- styles.welcome
- } > Loading < /Text> < ActivityIndicator / > < /View>)
- }
Now, will call the API and once we get the response we will set the isLoading to false and the datasource as movie object from the response.
- componentDidMount() {
- returnfetch('https://facebook.github.io/react-native/movies.json').then((response) => response.json()).then((responseJson) => {
- this.setState({
- isLoading: false,
- dataSource: responseJson.movies,
- }, function() {});
- }).catch((error) => {
- console.error(error);
- });
- }
Now, we need to create each item in the list. For that create a class named MyListItem, which will have the items which need to be populated for each list row.
- classMyListItemextendsReact.PureComponent {
- _onPress = () => {
- this.props.onPressItem(this.props.id);
- };
- render() {
- return ( < TouchableOpacityonPress = {
- this._onPress
- } > < Viewstyle = {
- styles.listItemView
- } > < Textstyle = {
- styles.headerText
- } > {
- this.props.title
- } < /Text> < Textstyle = {
- {
- color: "black"
- }
- } > {
- this.props.description
- } < /Text> < Viewstyle = {
- styles.dividerView
- }
- /> < /View> < /TouchableOpacity>);
- }
- }
Here, we have two text views and a divider at the bottom. We will show the film name and release year for each movie and a divider at the bottom. For that we defined some styles as well to customize each items.
- conststyles = StyleSheet.create({
- container: {
- flex: 1,
- justifyContent: 'center',
- alignItems: 'center',
- backgroundColor: '#F5FCFF',
- },
- welcome: {
- fontSize: 20,
- textAlign: 'center',
- margin: 10,
- color: 'green'
- },
- listItemView: {
- padding: 5,
- flexDirection: 'column'
- },
- headerText: {
- color: "red",
- fontWeight: 'bold',
- textAlign: 'left',
- fontSize: 20
- },
- dividerView: {
- borderBottomColor: 'black',
- borderBottomWidth: 1
- }
- });
Now, in the render() else part(whch means isLoading = false) we will show a FlatList, create a FlatList as below.
- return ( < View > < Textstyle = {
- styles.welcome
- } > Welcome < /Text> < FlatList data = {
- this.state.dataSource
- }
- renderItem = {
- this._renderItem
- }
- /> < /View>);
This will have data and renderItem. Data will be the JSON data which we got from the API response that we saved in the state. Datasource variable and the renderItem will be a function in which we can decide which data would be shown in which Textview.
- _renderItem = ({
- item
- }) => ( < MyListItem id = {
- item.id
- }
- title = {
- item.title
- }
- description = {
- item.releaseYear
- }
- />);
Which will set Id, title and descriptin to MyListItem class which we are rending in MyListItem class
- <Textstyle= {styles.headerText}> {this.props.title} </Text>
- <Textstyle= {{ color:"black" }}> {this.props.description} </Text>
That's it, so the entire file would look like.
- importReact, {
- Component
- }
- from 'react';
- import {
- StyleSheet,
- Text,
- View,
- FlatList,
- TouchableOpacity,
- ActivityIndicator
- } from 'react-native';
- exportdefaultclassAppextendsComponent {
- constructor(props) {
- super(props);
- this.state = {
- isLoading: true
- }
- }
- componentDidMount() {
- returnfetch('https://facebook.github.io/react-native/movies.json').then((response) => response.json()).then((responseJson) => {
- this.setState({
- isLoading: false,
- dataSource: responseJson.movies,
- }, function() {});
- }).catch((error) => {
- console.error(error);
- });
- }
- _renderItem = ({
- item
- }) => ( < MyListItem id = {
- item.id
- }
- title = {
- item.title
- }
- description = {
- item.releaseYear
- }
- />);
- render() {
- if (this.state.isLoading) {
- return ( < Viewstyle = {
- {
- flex: 1,
- padding: 20
- }
- } > < Textstyle = {
- styles.welcome
- } > Loading < /Text> < ActivityIndicator / > < /View>)
- }
- return ( < View > < Textstyle = {
- styles.welcome
- } > Welcome < /Text> < FlatList data = {
- this.state.dataSource
- }
- renderItem = {
- this._renderItem
- }
- /> < /View>);
- }
- }
- classMyListItemextendsReact.PureComponent {
- _onPress = () => {
- this.props.onPressItem(this.props.id);
- };
- render() {
- return ( < TouchableOpacityonPress = {
- this._onPress
- } > < Viewstyle = {
- styles.listItemView
- } > < Textstyle = {
- styles.headerText
- } > {
- this.props.title
- } < /Text> < Textstyle = {
- {
- color: "black"
- }
- } > {
- this.props.description
- } < /Text> < Viewstyle = {
- styles.dividerView
- }
- /> < /View> < /TouchableOpacity>);
- }
- }
- conststyles = StyleSheet.create({
- container: {
- flex: 1,
- justifyContent: 'center',
- alignItems: 'center',
- backgroundColor: '#F5FCFF',
- },
- welcome: {
- fontSize: 20,
- textAlign: 'center',
- margin: 10,
- color: 'green'
- },
- listItemView: {
- padding: 5,
- flexDirection: 'column'
- },
- headerText: {
- color: "red",
- fontWeight: 'bold',
- textAlign: 'left',
- fontSize: 20
- },
- dividerView: {
- borderBottomColor: 'black',
- borderBottomWidth: 1
- }
- });
Go to the project folder from the command line and run the command react-native start and open the Android folder in Android studio and run that project like a normal Android application. You can see the output:
The app is trying to fetch data from API, once it's done,
Happy coding, cheers.