Skip to content

Part 1: Fetching Some Data

Abel Lu edited this page Sep 30, 2024 · 6 revisions

In this section of the workshop, you will learn how to use async/await syntax to fetch data from the HackerNews API in your React Native application.

Setting Up

  1. Before we fetch any data, we need somewhere to store the data that we fetch. Add the following useState statement to your App.tsx:
    const [topStoryIds, setTopStoryIds] = useState([]);
    This initializes topStoryIds with an initial value of an empty array. This is important because as you may recall, the response from https://hacker-news.firebaseio.com/v0/topstories.json?print=pretty returns an array of numbers. By initializing with an empty array, we are declaring the type of data that will be stored in topStoryIds. To do this more explicitly, you can specify the type in angle brackets after useState and before its parentheses:
    const [topStoryIds, setTopStoryIds] = useState<number[]>([]);
  2. Fetching data can throw an error, and sometimes we'll want to show something on the screen in case the of an error. To handle these cases, let's add another useState statement to support this conditional rendering.
    const [error, setError] = useState<boolean>(false)[
  3. We've also decided that we only want to display the top 10 HackerNews stories for now. Add a constant to store this limit:
    const limit = 10;

Fetching the Data

  1. First, we need to define an asynchronous function that fetches data from the HackerNews API. Add the following code chunk to your App.tsx file directly above your return statement:

    async function getTopStoryIds() {
      setError(false);
      try {
        const res = await fetch("https://hacker-news.firebaseio.com/v0/topstories.json?print=pretty");
        const data = await res.json();
        setTopStoryIds(data);
      } catch {
        setError(true);
      }
    }
  2. Let's walk through the code chunk in step 1

    • setError(false):
      • This clear any errors that may have come up in previous fetch calls.
    • try {
      • This attempts to run the code in its following curly braces. If any errors come up, it stops and moves to the catch block.
    • const res = await fetch("https://hacker-news.firebaseio.com/v0/topstories.json?print=pretty");
      • Tries to fetch data from the specified URL, waiting on a result before continuing.
    • const data = await res.json();
      • Tries to convert the fetched data to a JSON object (an array in this case), waiting on a result before continuing.
    • setTopStoryIds(data);
      • Stores the formatted data in topStoryIds
    • catch {
      • If any errors come up in the try { block, exits the try { block and skip to the catch { block.
    • setError(true);
      • If errors come up, sets error to true to render an error message (we'll code this later)

    For more on async/await, read here.

  3. Add a useEffect statement after the async function definition and before the return statement to call the async function on the initial render:

      useEffect(() => {
        getTopStoryIds();
      }, [])

    Now when you run your Expo Go preview, the IDs top 500 HackerNews stories will be fetched on the initial render of your application. However, you will not be able to see any of this information, as we haven't added code to display it on the screen.

Displaying the Data

  1. The following code formats topStoryIds in an easily readable string:
    JSON.stringify(topStoryIds.slice(0, limit), null, 4)
    Replace the boilerplate text with the code above to display show the contents of topStoryIds on the screen.
  2. Save and reload your Expo Go preview, which should look something like this:

drawing

  1. While this works to view the contents of the array, we realistically want to be able to render something on the screen for each element in the list. Thats where the .map() methods comes in. Replace the <Text/> element containing the formatted JSON expression with the following code:

    {
      topStoryIds.slice(0, limit).map((storyId) => {
        return <Text key={storyId}>{storyId}</Text>;
      })
    }

    The .map() methods takes a callback function as an argument. The callback in this example tells React Native to render a <Text/> element for each storyId in the with the storyId as its contents for each storyId in the topStoryIds array. The key property in <Text/> element helps React Native keep track of which items in topStoryIds need to be re-rendered when the array changes, and needs to be unique for each item in the list. In this case, all storyIds are unique, so storyId works as a key.

  2. Save and refresh your Expo Go preview. Now, it should look something like this:

drawing

Observe how each story ID is on its own line and not separated by any square brackets or commas.

Next up: Part 2

Clone this wiki locally