Book Image

React Native By Example

By : Richard Kho
Book Image

React Native By Example

By: Richard Kho

Overview of this book

React Native's ability to build performant mobile applications with JavaScript has resulted in its popularity amongst developers. Developers now have the luxury to create incredible mobile experiences that look and feel native to their platforms with the comfort of a well-known language and the popular React.js library. This book will show you how to build your own native mobile applications for the iOS and Android platforms while leveraging the finesse and simplicity of JavaScript and React. Throughout the book you will build three projects, each of increasing complexity. You will also link up with the third-party Facebook SDK, convert an app to support the Redux architecture, and learn the process involved in making your apps available for sale on the iOS App Store and Google Play. At the end of this book, you will have learned and implemented a wide breadth of core APIs and components found in the React Native framework that are necessary in creating great mobile experiences.
Table of Contents (17 chapters)
Title Page
Credits
Foreword
About the Author
About the Reviewer
www.PacktPub.com
Customer Feedback
Preface

AsyncStorage


The AsyncStorage component is a simple key-value store that is globally available to your React Native application. It's persistent, meaning that data within AsyncStorage will continue to exist through quitting or restarting the application or your phone. If you've worked with HTML LocalStorage and SessionStorage, AsyncStorage will seem familiar. It's powerful for light usage, but Facebook recommends that you use an abstraction layer on top of AsyncStorage for anything more than that.

As the name implies, AsyncStorage is asynchronous. If you haven't yet been introduced to asynchronous JavaScript, this means the methods of this storage system can run concurrently with the rest of your code. The methods of AsyncStorage return a Promise--an object that represents an operation that hasn't yet completed, but is expected to in the future.

Each of the methods in AsyncStorage can accept a callback function as an argument, and will fire that callback once the Promise is fulfilled. This means that we can write our TasksList component to work around these promises, saving and retrieving our array of tasks when needed.

One final thing about AsyncStorage though--it's a simple key-value store. It expects a string for both its key and value, which means that we'll need to transform the data we send using JSON.stringify to turn the array into a string when sending it into storage and JSON.parse to transform it back into an array when retrieving it.

Play with AsyncStorage and update your TasksList component to support it. Here are some goals you'll want to have with AsyncStorage:

  • Once TasksList is loaded, we want to see whether any tasks exist locally in storage. If they do, present this list to the user. If they don't, start off with an empty array for storage. Data should always persist through a restart.
  • When a task is entered, we should update the list of tasks, save the updated list into AsyncStorage, and then update the ListView component.

Here's the code I ended up writing:

// TasksList/app/components/TasksList/index.js

... 
import { 
  AsyncStorage, 
  ... 
} from 'react-native'; 
... 

Import the AsyncStorage API from the React Native SDK.

export default class TasksList extends Component { 
  ... 
  componentDidMount () { 
    this._updateList(); 
  } 

Call the _updateList method during the componentDidMount life cycle.

  ... 
  async _addTask () { 
    const listOfTasks = [...this.state.listOfTasks, this.state.text]; 

    await AsyncStorage.setItem('listOfTasks', 
    JSON.stringify(listOfTasks)); 

    this._updateList(); 
  } 

 

 

Update _addTask to use the async and await keywords as well as AsyncStorage. Refer to the following for details on using async and await:

  ... 
  async _updateList () { 
    let response = await AsyncStorage.getItem('listOfTasks'); 
    let listOfTasks = await JSON.parse(response) || []; 

    this.setState({ 
      listOfTasks 
    }); 

    this._changeTextInputValue(''); 
  } 
} 

What we are doing with AsyncStorage in _updateTask is grabbing the value locally stored using the listOfTasks key. From here, we parse the result, transforming the string back into an array. Then, we check to see whether the array exists and set it to an empty array if it returns null. Finally, we set the state of our component by updating listOfTasks and firing _changeTextInputValue to reset TextInput value.

The preceding example also uses the new async and await keywords that are part of the ES7 specification proposal and readily available to use with React Native.

Using the Async and Await keywords

Normally, to deal with an asynchronous function, we would chain some promises to it in order to grab our data. We can write _updateList, like this:

_updateList () { 
  AsyncStorage.getItem('listOfTasks'); 
    .then((response) => {fto 
      return JSON.parse(response); 
    }) 
    .then((parsedResponse) => { 
      this.setState({ 
        listOfTasks: parsedResponse 
      }); 
    }); 
} 

 

 

However, this can become quite complicated. Instead, we will use the async and await keywords to create a simpler solution:

async _updateList () { 
  let response = await AsyncStorage.getItem('listOfTasks'); 
  let listOfTasks = await JSON.parse(response) || []; 

  this.setState({ 
    listOfTasks 
  }); 

  this._changeTextInputValue(''); 
} 

The async keyword in front of _updateList declares it as an asynchronous function. It automatically returns promises for us and can take advantage of the await keyword to tell the JS interpreter to temporarily exit the asynchronous function and resume running when the asynchronous call is completed. This is great for us because we can express our intent in a sequential order in a single function and still receive the exact same results that we would enjoy with a promise.