Build CRUD Mobile App using React Native, Elements, Navigation, Apollo Client and GraphQL

Build CRUD Mobile App using React Native, Elements, Navigation, Apollo Client and GraphQL

A comprehensive step by step tutorial on learn to build CRUD (Create, Read, Update, Delete) using React Native, Elements, Navigation, Apollo Client and GraphQL

A comprehensive step by step tutorial on learn to build CRUD (Create, Read, Update, Delete) using React Native, Elements, Navigation, Apollo Client and GraphQL

We will use existing Node.js, Express.js, MongoDB, and GraphQL that already created in React.js tutorial. So, we will focus on accessing GraphQL from the React Native Mobile Apps. Same exactly as React.js tutorial, we will use Apollo Client GraphQL to integrating with React Native.

The flow of CRUD Mobile Apps is very basic. It just the main page that shows the list of data, the details page, the edit, and the create data page. In this tutorial, we will use React Native and React Native Elements components including ScrollView, TextInput, Text, Button, View, etc. The list page contains a list of the book with the details button and a button to add new data on the right corner of the header. The details page contains data details text, the back button on the left corner of the header, an edit button and a delete button. The add-data page contains a React Native form, back button, and save button. The edit-data page contains the React Native form, back data, and update button. Simply as that, we will try to build this React Native Mobile Apps to Android and iOS devices.

The Example of React Native Navigation and Elements wrap together with Apollo Client GraphQL

The following tools, frameworks, and modules are required for this tutorial:

Before start to the main steps, make sure that you have installed Node.js and can run npm in the terminal or command line. To check the existing or installed Node.js environment open the terminal/command line then type this command.

node -v
v10.15.1
npm -v
6.9.0
yarn -v
1.10.1

React Native and Apollo GraphQL Tutorial: Install create-react-native-app and Create App

The create-react-native-app is a tool for creating a React Native App. To install it, type this command in your App projects folder.

sudo npm install -g create-react-native-app

Then create a React Native App using this create-react-native-app command.

create-react-native-app RnGraphql

If there question to install Expo, just type Y and choose a blank template because we will add the navigation later. That command will create a React Native app then install all required modules. The app or project folder will contain these folders and files.

|-- App.js
|-- app.json
|-- assets
| |-- icon.png
| `-- splash.png
|-- node_modules
`-- package.json

Next, go to the newly created React App folder.

cd RnGraphql

This React Native App is running via Expo app, before running on your Android or iOS device, make sure you have to install the Expo App to Android or Expo Client to iOS. Of course, that app is available in the App Store. So, we assume that you have installed the Expo App in your device then type this command to run the app.

npm start
or
yarn start

You will see this barcode and instruction in the terminal or command line.

To open the app in the Android device, open the Expo App first then tap on Scan QR Code button. Scan the barcode in the terminal or command line then you will see the React Native Android App like this after waiting for minutes the build process.

For iOS Device, press s from the keyboard to send React Native App URL to your Email or SMS. Enter your phone number or Email address (We use an email address) then press Enter. You will get this email to your mailbox.

Choose open in Expo URL then open in your browser, that will be redirected to Expo App. In Expo App welcome screen, shake your phone to open the React Native App. Now, you will see this screen in your iOS device.

Make sure you have the same network between your device and your development computer.

React Native and Apollo GraphQL Tutorial: Add Navigation Header and required Screen

As you see, the React Native app that you can only show plain text which unlike the standard Android or iOS Mobile Apps. To make a standard Android or iOS Mobile Apps, we need to add React Native header and navigation button with an icon to the React Native view. Type this command to install React Native Navigation (react-navigation).

yarn add react-navigation

Also, add the React Native Gesture Handler module by type this command.

yarn add react-native-gesture-handler

We have to link react-native to react-native-gesture-handler.

react-native link react-native-gesture-handler

Next, create a folder for components and components files in the root of the app folder by type these commands.

mkdir components
touch components/BooksScreen.js
touch components/BookDetailScreen.js
touch components/AddBookScreen.js
touch components/EditBookScreen.js

We will fill that files with simple React Native Button, Text, View, props, and navigation. Open and edit components/BooksScreen.js then add this React codes.

import React, { Component } from 'react';
import { Button, View, Text } from 'react-native';

class BooksScreen extends Component {
 static navigationOptions = {
  title: 'Books List',
 };
 render() {
  return (
   <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
    <Text>Books List</Text>
    <Button
     title="Go to Details"
     onPress={() => this.props.navigation.navigate('BookDetails')}
    />
    <Button
     title="Go to Add Book"
     onPress={() => this.props.navigation.navigate('AddBook')}
    />
    <Button
     title="Go to Edit Book"
     onPress={() => this.props.navigation.navigate('EditBook')}
    />
   </View>
  );
 }
}

export default BooksScreen;

Open and edit components/BookDetailScreen.js then add this React codes.

import React, { Component } from 'react';
import { Button, View, Text } from 'react-native';

class BookDetailScreen extends Component {
 static navigationOptions = {
  title: 'Book Details',
 };
 render() {
  return (
   <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
    <Text>Book Details</Text>
    <Button
     title="Go to Details... again"
     onPress={() => this.props.navigation.push('BookDetails')}
    />
    <Button
     title="Go to Home"
     onPress={() => this.props.navigation.navigate('Book')}
    />
    <Button
     title="Go back"
     onPress={() => this.props.navigation.goBack()}
    />
   </View>
  );
 }
}

export default BookDetailScreen;

Open and edit components/AddBookScreen.js then add this React codes.

import React, { Component } from 'react';
import { Button, View, Text } from 'react-native';

class AddBookScreen extends Component {
 static navigationOptions = {
  title: 'Add Book',
 };
 render() {
  return (
   <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
    <Text>Add Book</Text>
    <Button
     title="Go to Add Book... again"
     onPress={() => this.props.navigation.push('AddBook')}
    />
    <Button
     title="Go to Home"
     onPress={() => this.props.navigation.navigate('Book')}
    />
    <Button
     title="Go back"
     onPress={() => this.props.navigation.goBack()}
    />
   </View>
  );
 }
}

export default AddBookScreen;

Open and edit components/EditBookScreen.js then add this React codes.

import React, { Component } from 'react';
import { Button, View, Text } from 'react-native';

class EditBookScreen extends Component {
 static navigationOptions = {
  title: 'Edit Book',
 };
 render() {
  return (
   <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
    <Text>Add Book</Text>
    <Button
     title="Go to Edit Book... again"
     onPress={() => this.props.navigation.push('EditBook')}
    />
    <Button
     title="Go to Home"
     onPress={() => this.props.navigation.navigate('Book')}
    />
    <Button
     title="Go back"
     onPress={() => this.props.navigation.goBack()}
    />
   </View>
  );
 }
}

export default EditBookScreen;

Next, open and edit App.js then add replace all codes with this.

import { createStackNavigator, createAppContainer } from 'react-navigation';
import BooksScreen from './components/BooksScreen';
import BookDetailScreen from './components/BookDetailScreen';
import AddBookScreen from './components/AddBookScreen';
import EditBookScreen from './components/EditBookScreen';

const MainNavigator = createStackNavigator({
 Book: { screen: BooksScreen },
 BookDetails: { screen: BookDetailScreen },
 AddBook: { screen: AddBookScreen },
 EditBook: { screen: EditBookScreen },
});

const App = createAppContainer(MainNavigator);

export default App;

Next, run again the React Native app then refresh your Expo app. You will see the standard Android or iOS Mobile Apps in your device screen.

React Native and Apollo GraphQL Tutorial: Install and Configure Apollo Client GraphQL

Now, we have to install and configure all of the required modules and dependencies to the React Apollo *and *GraphQL. Type this command to install the modules at once.

yarn add react-apollo apollo-client apollo-cache-inmemory apollo-link-http graphql-tag graphql

Next, open and edit App.js then replace all imports with these imports.

import React from 'react';
import { AppRegistry } from 'react-native';
import { createStackNavigator, createAppContainer } from 'react-navigation';
import BooksScreen from './components/BooksScreen';
import BookDetailScreen from './components/BookDetailScreen';
import AddBookScreen from './components/AddBookScreen';
import EditBookScreen from './components/EditBookScreen';
import { ApolloClient } from 'apollo-client';
import { InMemoryCache } from 'apollo-cache-inmemory';
import { HttpLink } from 'apollo-link-http';
import { ApolloProvider } from 'react-apollo';

Change the constant name of createAppContainer constant variable.

const MyRootComponent = createAppContainer(MainNavigator);

Add these lines of Apollo Client constant variables.

const cache = new InMemoryCache();
const client = new ApolloClient({
 cache,
 link: new HttpLink({
    uri: 'http://localhost:3000/graphql',
 }),
});

const App = () => (
 <ApolloProvider client={client}>
  <MyRootComponent />
 </ApolloProvider>
);

Register the Apollo Provider by adding this line before the export line.

AppRegistry.registerComponent('MyApp', () => App);

React Native and Apollo GraphQL Tutorial: Show List of Books

To show the list of the books in the Books components, open and edit components/BooksScreen.js then add/replace these imports.

import React, { Component } from 'react';
import { StyleSheet, FlatList, ActivityIndicator, View, Text } from 'react-native';
import { ListItem, Button } from 'react-native-elements';
import gql from 'graphql-tag';
import { Query } from 'react-apollo';

As you can see, there are view elements that use react-native-elements module. For that, install the react-native-elements module first by type this command.

yarn add react-native-elements

Declare a constant before the class name for the query.

const GET_BOOKS = gql`
 {
  books {
   _id
   title
   author
  }
 }
`;

Replace navigationOptions with this.

static navigationOptions = ({ navigation }) => {
  return {
    title: 'LIST OF BOOKS',
    headerRight: (
    <Button
      buttonStyle={{ padding: 0, backgroundColor: 'transparent' }}
      icon={{ name: 'add-circle', style: { marginRight: 0, fontSize: 28 } }}
      onPress={() => { navigation.push('AddBook') }}
    />
    ),
  };
};

Add the function to extract and mapping result from GraphQL and render list item from the FlatList that will be added to the render section.

keyExtractor = (item, index) => index.toString()

renderItem = ({ item }) => (
  <ListItem
    title={item.title}
    onPress={() => {
      this.props.navigation.navigate('BookDetails', {
        id: `${item._id}`,
      });
    }}
    chevron
    bottomDivider
  />
)

Replace all React Native view render with Apollo Client GraphQL Query with pollInterval to make the page always request GraphQL data.

render() {
  return (
    <Query pollInterval={500} query={GET_BOOKS}>
      {({ loading, error, data }) => {
        if (loading) return(
          <View style={styles.activity}>
            <ActivityIndicator size="large" color="#0000ff"/>
          </View>
        );
        if (error) return(
          <View style={styles.activity}>
            <Text>`Error! ${error.message}`</Text>
          </View>
        );
        return (
          <FlatList
            keyExtractor={this.keyExtractor}
            data={data.books}
            renderItem={this.renderItem}
          />
        );
      }}
    </Query>
  );
}

Add React Native styles constant variables before the export code.

const styles = StyleSheet.create({
 container: {
   flex: 1,
   paddingBottom: 22
 },
 item: {
   padding: 10,
   fontSize: 18,
   height: 44,
 },
 activity: {
   position: 'absolute',
   left: 0,
   right: 0,
   top: 0,
   bottom: 0,
   alignItems: 'center',
   justifyContent: 'center'
 }
})

React Native and Apollo GraphQL Tutorial: Show a Book Details

To show book details, we have to modify components/BookDetailScreen.js then replace all imports with these imports.

import React, { Component } from 'react';
import { ScrollView, StyleSheet, ActivityIndicator, View, Text } from 'react-native';
import { Card, Button } from 'react-native-elements';
import gql from 'graphql-tag';
import { Query, Mutation } from 'react-apollo';

Declare the constant variables of the GraphQL gql or Queries.

const GET_BOOK = gql`
  query book($bookId: String) {
    book(id: $bookId) {
      _id
      isbn
      title
      author
      description
      published_year
      publisher
      updated_date
    }
  }
`;

const DELETE_BOOK = gql`
 mutation removeBook($id: String!) {
  removeBook(id:$id) {
   _id
  }
 }
`;

Modify the render section of the class to display a book details by implementing Apollo GraphQL Query and React Native ScrollView, Card, View, Button, Text, ActivityIndicator, etc.

class BookDetailScreen extends Component {
 static navigationOptions = {
  title: 'Book Details',
 };
 render() {
  const { navigation } = this.props;
  return (
    <Query pollInterval={500} query={GET_BOOK} variables={{ bookId: navigation.getParam('id') }}>
      {({ loading, error, data }) => {
        if (loading) return(<View style={styles.activity}>
          <ActivityIndicator size="large" color="#0000ff" />
         </View>);
        if (error) return(<Text>`Error! ${error.message}`</Text>);
        return (
          <ScrollView>
            <Card style={styles.container}>
              <View style={styles.subContainer}>
                <View>
                  <Text style={{fontSize: 16, fontWeight: 'bold'}}>ISBN:</Text>
                  <Text style={{fontSize: 18, marginBottom: 10}}>{data.book.isbn}</Text>
                </View>
                <View>
                  <Text style={{fontSize: 16, fontWeight: 'bold'}}>Title: </Text>
                  <Text style={{fontSize: 18, marginBottom: 10}}>{data.book.title}</Text>
                </View>
                <View>
                  <Text style={{fontSize: 16, fontWeight: 'bold'}}>Author: </Text>
                  <Text style={{fontSize: 18, marginBottom: 10}}>{data.book.author}</Text>
                </View>
                <View>
                  <Text style={{fontSize: 16, fontWeight: 'bold'}}>Description: </Text>
                  <Text style={{fontSize: 18, marginBottom: 10}}>{data.book.description}</Text>
                </View>
                <View>
                  <Text style={{fontSize: 16, fontWeight: 'bold'}}>Published Year: </Text>
                  <Text style={{fontSize: 18, marginBottom: 10}}>{data.book.published_year}</Text>
                </View>
                <View>
                  <Text style={{fontSize: 16, fontWeight: 'bold'}}>Publisher: </Text>
                  <Text style={{fontSize: 18, marginBottom: 10}}>{data.book.publisher}</Text>
                </View>
                <View>
                  <Text style={{fontSize: 16, fontWeight: 'bold'}}>Updated Date: </Text>
                  <Text style={{fontSize: 18}}>{data.book.updated_date}</Text>
                </View>
              </View>
              <Mutation mutation={DELETE_BOOK} key={data.book._id} onCompleted={() => navigation.goBack()}>
                {(removeBook, { loading2, error2 }) => (
                  <View style={styles.subContainer}>
                    <Button
                    style={styles.detailButton}
                    large
                    backgroundColor={'#CCCCCC'}
                    leftIcon={{name: 'edit'}}
                    title='Edit'
                    onPress={() => {
                      navigation.navigate('EditBook', { id: `${data.book._id}`, });
                    }} />
                    <Button
                    style={styles.detailButton}
                    large
                    backgroundColor={'#999999'}
                    color={'#FFFFFF'}
                    leftIcon={{name: 'delete'}}
                    title='Delete'
                    onPress={() => {
                      removeBook({ variables: { id: data.book._id } })
                      .then(res => res)
                      .catch(err => <Text>{err}</Text>);
                    }} />
                    {loading2 && <View style={styles.activity}>
                      <ActivityIndicator size="large" color="#0000ff" />
                     </View>}
                    {error2 && <Text>`Error! ${error2.message}`</Text>}
                  </View>
                )}
              </Mutation>
            </Card>
          </ScrollView>
        );
      }}
    </Query>
  );
 }
}

Modify or add the React Native style to match the modified details page.

const styles = StyleSheet.create({
  container: {
    flex: 1,
    padding: 20
  },
  subContainer: {
    flex: 1,
    paddingBottom: 20,
    borderBottomWidth: 2,
    borderBottomColor: '#CCCCCC',
  },
  activity: {
    position: 'absolute',
    left: 0,
    right: 0,
    top: 0,
    bottom: 0,
    alignItems: 'center',
    justifyContent: 'center'
  },
  detailButton: {
    marginTop: 10
  }
})

React Native and Apollo GraphQL Tutorial: Add a New Book

To add a new book, we have an add button in the List of Book page that will push the Add Page. This Add Page will use Apollo GraphQL Mutation instead of React Form. The React Native TextInput change will use a function that triggers the OnChange event. Open and edit components/AddBookScreen.js then replace all imports with these imports.

import React, { Component } from 'react';
import { StyleSheet, ScrollView, ActivityIndicator, View, TextInput, Text } from 'react-native';
import { Button } from 'react-native-elements';
import gql from "graphql-tag";
import { Mutation } from "react-apollo";

Declare a constant variable of the Apollo GraphQL gql or Query before the class name.

const ADD_BOOK = gql`
  mutation AddBook(
    $isbn: String!,
    $title: String!,
    $author: String!,
    $description: String!,
    $publisher: String!,
    $published_year: Int!) {
    addBook(
      isbn: $isbn,
      title: $title,
      author: $author,
      description: $description,
      publisher: $publisher,
      published_year: $published_year) {
      _id
    }
  }
`;

Add an object of the state after the navigationOptions that consists of required fields that match the GraphQL data.

state = {
 isbn: '',
 title: '',
 author: '',
 description: '',
 published_year: '',
 publisher: '',
}

Add a function to update the React Native TextInput value and state object values.

updateTextInput = (text, field) => {
 const state = this.state
 state[field] = text;
 this.setState(state);
}

Modify the React Native render section to add Apollo GraphQL Mutation, React Native TextInput, ScrollView, View, ActivityIndicator, etc.

render() {
  const { isbn, title, author, description, published_year, publisher } = this.state;
  return (
   <Mutation mutation={ADD_BOOK} onCompleted={() => this.props.navigation.goBack()}>
     {(addBook, { loading, error }) => (
      <ScrollView style={styles.container}>
       <View style={styles.subContainer}>
        <TextInput
          style={styles.textInput}
          placeholder={'ISBN'}
          value={this.state.isbn}
          onChangeText={(text) => this.updateTextInput(text, 'isbn')}
        />
       </View>
       <View style={styles.subContainer}>
        <TextInput
          style={styles.textInput}
          placeholder={'Title'}
          value={this.state.title}
          onChangeText={(text) => this.updateTextInput(text, 'title')}
        />
       </View>
       <View style={styles.subContainer}>
        <TextInput
          style={styles.textInput}
          placeholder={'Author'}
          value={this.state.author}
          onChangeText={(text) => this.updateTextInput(text, 'author')}
        />
       </View>
       <View style={styles.subContainer}>
        <TextInput
          style={styles.textInput}
          placeholder={'Description'}
          multiline={true}
          numberOfLines={4}
          value={this.state.description}
          onChangeText={(text) => this.updateTextInput(text, 'description')}
        />
       </View>
       <View style={styles.subContainer}>
        <TextInput
          style={styles.textInput}
          placeholder={'Published Year'}
          value={this.state.published_year}
          keyboardType='numeric'
          onChangeText={(text) => this.updateTextInput(text, 'published_year')}
        />
       </View>
       <View style={styles.subContainer}>
        <TextInput
          style={styles.textInput}
          placeholder={'Publisher'}
          value={this.state.publisher}
          onChangeText={(text) => this.updateTextInput(text, 'publisher')}
        />
       </View>
       <View>
        <Button
         large
         leftIcon={{name: 'save'}}
         title='Save'
         onPress={() => {
          addBook({
           variables: {
            isbn: this.state.isbn,
            title: this.state.title,
            author: this.state.author,
            description: this.state.description,
            publisher: this.state.publisher,
            published_year: parseInt(this.state.published_year),
           }
          })
           .then(res => this.setState({ isbn: '', title: '', author: '', description: '', published_year: '', publisher }))
           .catch(err => <Text>{err}</Text>);
         }} />
       </View>
       {loading && <View style={styles.activity}>
         <ActivityIndicator size="large" color="#0000ff" />
        </View>}
       {error && <Text>`Error! ${error.message}`</Text>}
      </ScrollView>
     )}
    </Mutation>
  );
 }
}

Also, modify the React Native style to match the required views.

const styles = StyleSheet.create({
 container: {
  flex: 1,
  padding: 20
 },
 subContainer: {
  flex: 1,
  marginBottom: 20,
  padding: 5,
  borderBottomWidth: 2,
  borderBottomColor: '#CCCCCC',
 },
 activity: {
  position: 'absolute',
  left: 0,
  right: 0,
  top: 0,
  bottom: 0,
  alignItems: 'center',
  justifyContent: 'center'
 },
 textInput: {
  fontSize: 18,
  margin: 5,
 },
})

React Native and Apollo GraphQL Tutorial: Edit a Book

The Edit Book Screen pushed from the Book Details Screen. Same as the previous Add Book Page, this page will contain the Apollo GraphQL Mutation and React Native TextInput with additional Apollo GraphQL Query. All React Native TextInput will fill with the data from GraphQL Query. Open and edit components/EditBookScreen.js then replace all imports with these imports.

import React, { Component } from 'react';
import { StyleSheet, ScrollView, ActivityIndicator, View, TextInput, Text } from 'react-native';
import { Button } from 'react-native-elements';
import gql from "graphql-tag";
import { Query, Mutation } from "react-apollo";

Declare the constant variables of the Apollo GraphQL Query or gql after the imports.

const GET_BOOK = gql`
  query book($bookId: String) {
    book(id: $bookId) {
      _id
      isbn
      title
      author
      description
      published_year
      publisher
      updated_date
    }
  }
`;

const UPDATE_BOOK = gql`
  mutation updateBook(
    $id: String!,
    $isbn: String!,
    $title: String!,
    $author: String!,
    $description: String!,
    $publisher: String!,
    $published_year: Int!) {
    updateBook(
    id: $id,
    isbn: $isbn,
    title: $title,
    author: $author,
    description: $description,
    publisher: $publisher,
    published_year: $published_year) {
      updated_date
    }
  }
`;

The above constant variables are Apollo GraphQL Query of the GET and the UPDATE Book data. Next, inside the main class, add an object of the state that contains required fields.

state = {
 isbn: '',
 title: '',
 author: '',
 description: '',
 published_year: '',
 publisher: '',
}

Add a function to update only the state instead of the state and the fields because the fields will fill with the data from GraphQL. In this case, you can't call setState twice to fill the state, so, we fill the state and the fields separately.

updateTextInput = (text, field) => {
 const state = this.state
 state[field] = text;
 this.setState(state);
}

Modify the React Native render section to Apollo GraphQL Query, Mutation, React Native ScrollView, View, TextInput, Button, etc.

render() {
  const { navigation } = this.props;
  const { isbn, title, author, description, published_year, publisher } = this.state;
  return (
   <Query query={GET_BOOK} variables={{ bookId: navigation.getParam('id') }}>
    {({ loading, error, data }) => {
     if (loading) return(<View style={styles.activity}>
       <ActivityIndicator size="large" color="#0000ff" />
      </View>);
     if (error) return(<Text>`Error! ${error.message}`</Text>);
     return (
      <Mutation mutation={UPDATE_BOOK} key={data.book._id} onCompleted={() => navigation.goBack()}>
       {(updateBook, { loading2, error2 }) => (
        <ScrollView style={styles.container}>
         <View style={styles.subContainer}>
          <TextInput
            style={styles.textInput}
            placeholder={'ISBN'}
            defaultValue={data.book.isbn}
            onChangeText={(text) => this.updateTextInput(text, 'isbn')}
          />
         </View>
         <View style={styles.subContainer}>
          <TextInput
            style={styles.textInput}
            placeholder={'Title'}
            defaultValue={data.book.title}
            onChangeText={(text) => this.updateTextInput(text, 'title')}
          />
         </View>
         <View style={styles.subContainer}>
          <TextInput
            style={styles.textInput}
            placeholder={'Author'}
            defaultValue={data.book.author}
            onChangeText={(text) => this.updateTextInput(text, 'author')}
          />
         </View>
         <View style={styles.subContainer}>
          <TextInput
            style={styles.textInput}
            placeholder={'Description'}
            multiline={true}
            numberOfLines={4}
            defaultValue={data.book.description}
            onChangeText={(text) => this.updateTextInput(text, 'description')}
          />
         </View>
         <View style={styles.subContainer}>
          <TextInput
            style={styles.textInput}
            placeholder={'Published Year'}
            defaultValue={data.book.published_year.toString()}
            keyboardType='numeric'
            onChangeText={(text) => this.updateTextInput(text, 'published_year')}
          />
         </View>
         <View style={styles.subContainer}>
          <TextInput
            style={styles.textInput}
            placeholder={'Publisher'}
            defaultValue={data.book.publisher}
            onChangeText={(text) => this.updateTextInput(text, 'publisher')}
          />
         </View>
         <View>
          <Button
           large
           leftIcon={{name: 'save'}}
           title='Save'
           onPress={() => {
            if (this.state.isbn === '')
             this.state.isbn = data.book.isbn;
            if (this.state.title === '')
             this.state.title = data.book.title;
            if (this.state.author === '')
             this.state.author = data.book.author;
            if (this.state.description === '')
             this.state.description = data.book.description;
            if (this.state.publisher === '')
             this.state.publisher = data.book.publisher;
            if (this.state.published_year === '')
             this.state.published_year = data.book.published_year;
            updateBook({
             variables: {
              id: data.book._id,
              isbn: this.state.isbn,
              title: this.state.title,
              author: this.state.author,
              description: this.state.description,
              publisher: this.state.publisher,
              published_year: parseInt(this.state.published_year),
             }
            })
             .then(res => res)
             .catch(err => <Text>{err}</Text>);
           }} />
         </View>
         {loading2 && <View style={styles.activity}>
           <ActivityIndicator size="large" color="#0000ff" />
          </View>}
         {error2 && <Text>`Error! ${error2.message}`</Text>}
        </ScrollView>
       )}
      </Mutation>
     );
    }}
   </Query>
  );
 }
}

Modify the React Native style to match the view requirements.

const styles = StyleSheet.create({
 container: {
  flex: 1,
  padding: 20
 },
 subContainer: {
  flex: 1,
  marginBottom: 20,
  padding: 5,
  borderBottomWidth: 2,
  borderBottomColor: '#CCCCCC',
 },
 activity: {
  position: 'absolute',
  left: 0,
  right: 0,
  top: 0,
  bottom: 0,
  alignItems: 'center',
  justifyContent: 'center'
 },
 textInput: {
  fontSize: 18,
  margin: 5,
 },
})

React Native and Apollo GraphQL Tutorial: Run and Test the Mobile Apps

Before running the React Native apps, we have to download and run the Node.js, Express.js, MongoDB GraphQL server. After download and install the required Node modules, run first the MongoDB server in the different terminal tab.

mongod

Run the Express.js GraphQL server in another terminal tab.

nodemon

In the current React Native app terminal tab, run the React Native app.

yarn start

Open again the Expo app on your iOS or Android device then refresh the current running React Native application. And here they are the full React Native Mobile Apps running with Apollo GraphQL data.

That it's, the React Native and Apollo GraphQL Tutorial: Build Mobile Apps with React Native Elements and Navigation. You can find the full source code from our GitHub.

mobile-apps react-native apollo graphql

Bootstrap 5 Complete Course with Examples

Bootstrap 5 Tutorial - Bootstrap 5 Crash Course for Beginners

Nest.JS Tutorial for Beginners

Hello Vue 3: A First Look at Vue 3 and the Composition API

Building a simple Applications with Vue 3

Deno Crash Course: Explore Deno and Create a full REST API with Deno

How to Build a Real-time Chat App with Deno and WebSockets

Convert HTML to Markdown Online

HTML entity encoder decoder Online

How native is React Native? | React Native vs Native App Development

Article covers: How native is react native?, React Native vs (Ionic, Cordova), Similarities and difference between React Native and Native App Development.

React Native Mobile App Development

Skenix is providing React Native Development Services with qualified React Native App Developers. Get the best React Native App Development Services.

Top React Native Mobile App Development Companies in USA

Looking for top React Native mobile app development company in USA for Startups & Enterprise? Find out the top list of React Native mobile app development company in USA.

Which is the best React Native app development company in New York?

Hire top react native app development company in New York to build and develop custom react native mobile apps for Android & iOS with the latest features.

Create React Native eCommerce Mobile App

Find out how to build eCommerce mobile application with React Native. Tips and tricks to save time, efforts, and money.