How to test networking latency in React Native

In my previous post, I tested my React Native app to see what would happen if a fetch to get data from a URL resulted in an error. In my experience, URLs don’t just fail with a 404 error, however. Sometimes there’s a time delay in getting a response from a URL. This is sometimes called latency or a lag.

I wanted to see how my app would behave if the URL that it fetched had a long delay in responding. But I didn’t have a URL that would reliably take a long time to respond! How could I mimic this situation? That’s what I’ll address in this blog post.

My app does the fetch in the componentDidMount method, and then sets state to update the display, like this:

componentDidMount() {
    return fetch('https://facebook.github.io/react-native/movies.json')
        .then((response) => response.json())
        .then((responseJson) => {
            this.setState({
                isLoading: false,
                dataSource: responseJson.movies,
            });
        })
        .catch((error) => {
            // TODO FIXME replace the red screen with something informative.
            console.error(error);
        });
}

My initial attempt at adding a delay was to set a timeout around the setState call, but this resulted in an error. To simplify the code and make it easier to test, I moved the call to setState into a separate, reusable chunk of code, like this:

setMovieState(movies) {
    this.setState({
        isLoading: false,
        dataSource: movies,
    });
}

So then my componentDidMount becomes:

componentDidMount() {
    return fetch('https://facebook.github.io/react-native/movies.json')
        .then((response) => response.json())
        .then((responseJson) => {
            this.setMovieState(responseJson.movies);
        })
        .catch((error) => {
            // TODO FIXME replace the red screen with something informative.
            console.error(error);
        });
}

That looks a little cleaner, but I still need to do something to introduce a lag.

Let me write a new little piece of code which calls the method setMovieState after a specified delay:

handleMoviesResponse(movies, delay) {
    if (delay && delay > 0) {
        const timer = setTimeout(function () {
            this.setMovieState(movies);
        }.bind(this), delay);
    } else {
        this.setMovieState(movies);
    }
}

If there’s no delay, the state will be set immediately. If the method is called with a delay, then the state is not updated until after the input delay.

If you’re wondering what bind(this) is about, you may not be too familiar with JavaScript. A short answer is that the anonymous function that is passed to setTimeout uses this inside it, and that function needs to know what this is (this is my app which contains the method setMovieState.)

Finally, instead of calling setMovieState from componentDidMount, I call handleMoviesResponse, like this:

this.handleMoviesResponse(responseJson.movies, 5000);

Now that I’ve done this, I can see that when my app opens, I just see a plain white screen for 5 seconds, and then I see my movie titles dropdown (Picker) appear at the top of the page. It’s not a crash, but it seems like a bad user experience. In my next post, I’ll look at how to fix that.

blank screen when there’s network latency

Got comments? Send them to me in an email at fullstackdev@fullstackoasis.com. If you found this interesting, go ahead and click the subscribe button above. I write a new post about once a week.

1 thought on “How to test networking latency in React Native

  1. Pingback: How to add a progress loader in React Native | Full Stack Oasis

Leave a Reply

Your email address will not be published. Required fields are marked *