How To Build WordPress Client App with React Native Part #20: Saving Data to Cache

Written by krissanawat101 | Published 2020/01/08
Tech Story Tags: react-native | react | software-development | tutorial | beginners | mobile-apps | mobile-development | application | web-monetization

TLDR This series intends to show how I build an app to serve content from my WordPress blog by using react-native. The inspiration to do this tutorial series came from the React Native App Templates from instamobile. We will learn how to set-up many packages that make our lives comfortable. We store the latest post into AsyncStorage in five screens that have remote data. In Android Emulator, our app will not be able to run in the offline mode. We can also use the netinfo package to display the offline icon in the header by checking the network status of the device.via the TL;DR App

This series intends to show how I build an app to serve content from my WordPress blog by using react-native. Since my blog is talking about react-native, the series and the articles are interconnected. We will learn how to set-up many packages that make our lives comfortable and learn how to deal with WordPress APIs. Here, the most prominent features talked about in the book are the dark theme, offline mode, infinite scroll and many more. You can discover much more in this series. this inspiration to do this tutorial series came from the React Native App Templates from instamobile
Here, we are going to save the article data to cache so that the users can still access some articles during offline mode. For that, we store the latest post into AsyncStorage in five screens that have remote data.
Here, we are going to start with the Home.js file.

In Home.js

Here, we first import the NetInfo package and AsyncStorage package. We also need to set the cacheKey so that we can identify the cache data for each screen.
 import NetInfo from '@react-native-community/netinfo';
    import AsyncStorage from '@react-native-community/async-storage';
    const cacheKey = 'CacheData';
Now, we need to update the functions that fetches the posts using following code:
 try {
          const networkState = await NetInfo.fetch();
          if (!networkState.isConnected) {
            const _cachedData = await AsyncStorage.getItem(cacheKey);
            if (!_cachedData) {
              throw new Error(
                "You're currently offline and no local data was found.",
              );
            }
Here, we first check the connection using the isConnected state of the
NetInfo module. If the connection is false then, we load the cache not found error.
Then, we load the data from the cache and set it to the posts data in order to display in the screen as shown in the code snippet below:
    const cachedData = JSON.parse(_cachedData);
         this.setState({
           lastestpost: cachedData.post,
           isFetching: false,
         });
       }
If the connection is active, then we load the data from the WordPress API just as before as shown in the code snippet below:
    let page = this.state.page;
          const response = await fetch(
            `https://kriss.io/wp-json/wp/v2/posts?per_page=5&page=${page}`,
          );
          const post = await response.json();
          await AsyncStorage.setItem(
            cacheKey,
            JSON.stringify({
              post,
            }),
          );
So, if we are online then we store the latest post to the AsyncStorage for
caching. So that, the same data can be loaded when we are offline.

In SinglePost.js

Here, we do the same thing as the Home.js screen. The only difference is that we need to load a single post.
For that, we are going to filter the posts in the cache before displaying the
post data in the offline mode. In order to implement this, we need to use the code from the following code snippet:
    const cachedData = JSON.parse(_cachedData);
           let post = cachedData.post.filter(value => value.id === post_id);
           this.setState({
             post: post,
             isloading: false,
             offline: true,
           });

In Categories.js

We do the same thing in Categories.js as on the Home.js screen. But, we need to change the cacheKey as shown in the code snippet below:
   const cacheKey = 'CategoriesCache';

In Bookmark.js

We do the same thing in Bookmark.js as on the Home.js screen. But, we need to change the cacheKey as shown in the code snippet below:
  const cacheKey = 'Bookmark';
Hence, we will get the following result in the emulator screens:
As we can see, we can access the post data even when we are offline. The network info is also displayed.

In Android Emulator

In case of Android, If we go into offline mode then our app loses its connection to the metro bundler server. Hence, we will not be able to run our app in the offline. This is shown by the emulator simulation below:
Now, in order to solve this issue, we need to run our application in the
emulator without the development server like the metro bundler. For that, we need to make some configurations to our build.gradle file in the
'./android/app/' folder.
In our ./android/app/build.gradle file, we can see a large commented out block that explains which settings you can set in the project.ext.react map inside your gradle file.
We need to search for project.ext.react map in our gradle configuration file
and add the 
bundleInDebug: true
 entry as shown in the code snippet below:
  project.ext.react = [
        entryFile: "index.js",
        enableHermes: false,  // clean and rebuild if changing
        bundleInDebug: true,
    ]project.ext.react = [
        entryFile: "index.js",
        enableHermes: false,  // clean and rebuild if changing
        bundleInDebug: true,
    ]
This will configure gradle to actually bundle the JS code and assets and package those files into the APK instead of serving them up from the dev server.
Now, if we run our app in the emulator, we will get the yellow warnings at the bottom. In order to prevent that, we need to add
devDisabledInDebug: true 
to following code:
    project.ext.react = [
        entryFile: "index.js",
        enableHermes: false,  // clean and rebuild if changing
        bundleInDebug: true,
        devDisabledInDebug: true
    ]
Now, we can run our project in the Android emulator without the metro bundler server. Hence, we run the app using react-native run-android, we will get the following result in our Android emulator:
As we can see, we can now run the app properly in offline mode. We can also see that the data is cached from the AsyncStorage.
Note that, if we want our metro bundler to work then, we can simply remove the codes we added in the build.gradle file. There are lots of advantages using a metro bundler development server like debugging and hot reloading.

Summary

In this chapter, we learned how to implement the offline mode in the react native app. We used the netinfo package to display the offline icon in the header by checking the network status of the device. Then, we use the save package to handle the loading the data from cache or from the API. If the app is in offline mode, we display the cached data. We load the data into cache when we are online and we have the latest post. In this way, we successfully learned how to implement the offline mode in the app.

Written by krissanawat101 | React native Developer ,Coffee addict
Published by HackerNoon on 2020/01/08