React Native Guide - Creating an iOS App Part 1.2, 1.3

    → Transfer from here
    → Continued. Start here

    2. Extracting data from the API


    In this section, we will connect to the Unsplash.it site API and request wallpaper information. But before we get down to the fun, we need to do something.

    ES2015 style class declaration


    In the index.ios.js file , you see the existing code. He is responsible for outputting the contents to the emulator.

    image

    In the index.ios.js file , we see a line var SplashWalls = React.createClass({ ... }). We will change it. In this guide, we will use the ES2015 syntax to declare classes.
    We developers are curious. You might want to ask: “Why? Why use classes from ES2015? ”

    Everything is explained by personal preferences. I programmed a lot in OOP languages ​​and classit is closer to me than function. In addition, using classwe can write cleaner code, because we do not need to add (;) after the declaration of each method.

    On the other hand, we lose some "chips", such as binding or access to the isMounted () method, although this is not so important, because you will not lose much, not using them.

    A class can be created in any way. I recommend it class. This is a new “trick” and sooner or later you will have to use ES2015. Using this guide, you have to use the ES2015 syntax, you just have no choice!

    You can read more about this in the article “React.Component vs React.createClass” by Naman Goel and Zach Silveira.

    After making the changes, the code should look like this:

    class SplashWalls extends Component{
      render() {
        return (
      . 
              Welcome to React Native!
            
              To get started, edit index.ios.js
            
              Press Cmd+R to reload,{'\n'}
              Cmd+D or shake for dev menu
            
       .
        );
      }
    };
    

    To people unfamiliar with React, the code in braces may seem a little strange. But this is the usual XML-like syntax called JSX. Read more here .

    Hey! And what is this Component whose instance we are creating? And that is the right question. If we start the project now, we get an error that says that Component is not declared. There are two ways to fix this: replace Component with React.Component or import Component as shown below.

    In this and the following code examples, I will wrap new pieces of code in /***/to make it easier for you to track changes. If you will copy the code from here, make sure that you do not copy /***/along with the code. JSX does not support view comments /*...*/so by inserting such comments you won’t be able to launch the application.

    'use strict';
    var {
      AppRegistry,
      StyleSheet,
      Tex .t,
      View,
      /***/
      Component 
      /***/
    } = React;
    

    The code above eliminates the need to write extra code. If you do not insert these lines of code, you will have to write React.AppRegistry instead of AppRegistry. Not bad, right? Return to Xcode and run the project again to make sure everything works.

    The first thing we should do is add a constructor to the SplashWalls class. In the constructor, we initialize state variables. At the moment, we need two variables:

    • wallsJSON, the array that will contain json obtained from the API
    • isLoading - a variable containing the value true / false and changing its value depending on whether the data is received or not.

    Add a constructor to the code as shown below:

    class SplashWalls extends Component{
    /***/
      constructor(props) {
        super(props);
        this.state = {
          wallsJSON: [],
          isLoading: true
        };
      }
    /***/
    ...
    }

    Now we will create a fetchWallsJSON method that will receive json data. Leave a few lines from the closing brackets of the constructor and add the following:

    fetchWallsJSON() {
    	console.log(‘Wallpapers will be fetched’);
    }

    We want this function to run as soon as our component is successfully mounted. Add a method componentDidMount(). Most methods will be added to the SplashWalls class. I will mention separately if the methods are added elsewhere.

    componentDidMount()Is a lifecycle method that starts immediately after the first rendering of the React component.


    Here you can read more about the life cycle methods of the React component. Since we are using ES2015 syntax, we can omit the getInitialState method. It is replaced by the declaration of the this.state variable in the constructor.

    I like to separate the methods I create from the life cycle methods. You should follow the same rule.

    Let's declare a method componentDidMount():

    componentDidMount() {
    	this.fetchWallsJSON();
    }

    Please note that in the method fetchWallsJSON()we display a message in the console. And where is the console itself? Let's get a look.

    Make sure the emulator window is in focus and press Cmd + Control + Z. From the pop-up menu, select Debug in Chrome (debugging in Chrome). A new tab will open. In the same tab, go to Developer Tools (Option + Cmd + J). In the console you will see the message “Wallpapers will be fetched”.


    Do not close the debug window yet. Go to unsplash.it/list in a new tab. The tab area should be filled with a JSON array. Each element in it is a JS object containing data about a separate wallpaper file.

    Let's make the fetchWallsJSON () method do more than just print a message to the console.

     fetchWallsJSON() {
    	/***/
        var url = 'http://unsplash.it/list';
        fetch(url)
          .then( response => response.json() )
          .then( jsonData => {
            console.log(jsonData);
          })
    	.catch( error => console.log(‘Fetch error ‘ + error) );
    	/***/
      }

    Update the emulator (Cmd + R) or, better, enable live reload by pressing Cmd + Ctrl + Z and selecting “Enable live reload”. Having activated live reboot, you will not need to update the emulator every time after changing the code. Just save the file in your IDE and the emulator will automatically update the rendering. If you previously developed applications in Xcode or Android Studio, you will really like this “trick”, because you will get rid of the need to recompile the application each time (as they said at one RN conference, now you will not have time for a cup of tea (- “Rendered!”), As before - approx. Translator).

    After some time, after making changes, you should see the following in the emulator:


    Great, we were able to get JSON data from the API. If you notice, there was some delay before the message appeared in the console. It is due to the fact that the data was downloaded from the server, which takes some time.

    It seems time to add a screen showing the download.

    Boot screen


    Towards the end of this section, we will make a loading screen that will be displayed during the loading of JSON data.

    First, clear everything in the render()class method SplashWalland add the following lines of code:

    render() {
        var {isLoading} = this.state;
        if(isLoading)
          return this.renderLoadingMessage();
        else
          return this.renderResults();
      }
    

    We have indicated two new methods. Let's declare them:

      renderLoadingMessage() {
        return (
      . Contacting Unsplash
       .
        );
      }
      renderResults() {
        return (
      . 
              Data loaded
            
       .
        );
      }
    

    Depending on the value of the isLoading variable, two View components will be drawn. If the isLoading value is true, we will display the download progress bar and the text “Contacting Unsplash” (“Connect to Unsplash”). Otherwise, we will display the data, instead of which at the moment we will display the text "Data loaded" ("Data loaded").

    However, we forgot something: we do not change the value of the isLoading variable after loading the data. Let's do that. Let's go back to the method fetchWallsJSON and add something:

    fetchWallsJSON() {
        var url = 'http://unsplash.it/list';
        fetch(url)
          .then( response => response.json() )
          .then( jsonData => {
            console.log(jsonData);
    	/***/
            this.setState({isLoading: false}); //update isLoading 
    	/***/
          })
    	.catch( error => console.log(‘Fetch error ‘ + error) );
      }
    

    setState- This is one of the methods React’s Component API. This is the main method used to start updating the user interface.

    Please note in the method renderLoadingMessagewe use the new component ActivityIndicatorIOS(loading indicator). We need to import it so that we can use it:

    'use strict';
    var {
      AppRegistry,
      StyleSheet,
      Tex .t,
      View,
      Component,
    /***/
      ActivityIndicatorIOS // Add new component
    /***/
    } = React;
    

    We need to do one more thing before we can enjoy the result. If you notice, the View component that contains the ActivityIndicatorIOS loading indicator has the styles.loadingContainer style. We need to set this style. We need to find a piece of code starting with words var styles = StyleSheet.create({….. In this block of code, we can see the styles that are already defined. They refer to the default message “Welcome to React Native”. Delete all styles and set styles for loadingContainer as shown below:

    var styles = StyleSheet.create({
    /***/
      loadingContainer: {
    	flex: 1,
        flexDirection: 'row’,
        justifyContent: 'center',
        alignItems: 'center',
        backgroundColor: '#000'
      }
    /***/
    });
    

    All styles that apply to components in RN are defined in the same way. StyleSheet.create accepts a JS object containing styles. After that, you can access the style using the dot operator [.]. Just as we applied the style for View:


    Styles can also be specified in the line:


    This unnecessarily clutters the code. Therefore, styles are best stored in a variable.

    Styles are very similar to CSS, right? This makes RN even easier for web developers. When you are working in an IDE (Xcode, for example), you have a StoryBoard, which allows you to directly drag and position UI elements such as buttons. In RN, this cannot be done, but it is not so bad after all.

    React Native uses flexbox to position items on the screen . Having mastered flexbox, it will not be difficult for you to position the elements. This is one of those things that you must try to understand the difference.

    Save the changes, go to the emulator and press Cmd + R. You should see the boot screen, and then the screen that says “Data loaded”:



    In the next section, we will add wallpaper filtering.

    Also popular now: