Fetch & display data using the Airtable API and React
Tags: react, airtable, tutorial
Published: 2021-03-25 05:27:49

In this tutorial we’ll be using Airtable as a data source for a simple React application. If you’re not familiar with Airtable they describe themselves as having the power of a database with the familiarity of a spreadsheet. If you know your way around spreadsheets you’ll have no troubles working with Airtable.

The completed source code can be found on GitHub:

{% github w3collective/react-airtable %}

We’ll start with the Airtable setup before moving onto the code. Sign up for a new Airtable account if you haven’t already. Feel free to use this [referral link](https://airtable.com/invite/r/SVFLWUlx) and I’ll receive $10 in Airtable credit.

Airtable is quite simple to use so you may just want to import the data I used when creating this tutorial from [here](https://airtable.com/shrvGRzY7TkqfP6lf/tblRwrCcTpIJBInDu). Otherwise the steps involved in setting up the data are as follows:

- Create a new base (Airtable’s name for a database).
- Change the title and table name to recipes.
- Rename the first field (Name) to recipe.
- Delete the Notes, Attachments, & Status fields.
- Add new url & photo fields.

Here’s what my base looked like after being populated with some data:

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/tf9ylgajxrlxxdlle05y.gif)

We can now move onto creating the component to display this data in React. We’ll use Create React App to setup the development environment but this component can easily be dropped in an exiting application:

```
npx create-react-app react-airtable
```

Next create a new `Recipes.js` file in the `/src` directory with the imports:

```javascript
import React, { useEffect, useState } from "react";

const Recipes = () => {
  //...
  return (<div/>);
}

export default Recipes;
```

First up in the `Recipes` function we’ll define the variables for the `useState` Hook:

```javascript
const [recipes, setRecipes] = useState({});
```

We’l then use the Fetch API inside a useEffect Hook to retrieve the data:

```javascript
useEffect(() => {
  fetch("https://api.airtable.com/v0/appM9q6JTxRolaNCN/recipes?api_key=YOUR_API_KEY")
    .then((res) => res.json())
    .then((data) => {
      setRecipes(data.records);
      console.log(data);
    })
    .catch((error) => {
      console.log(error);
    });
}, []);
```

To get the URL used in the fetch request you first need to generate an API key on the [Account page](https://airtable.com/account), be sure to keep this secure. Next visit the [API dashboard](https://airtable.com/api) and select your base. Scroll to the “Authentication” section and copy the example query parameter.

If the request was successful you’ll be able to see the data logged in the console:

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dx94d1skh8dr13h07f86.gif)

With the data fetched and saved we can loop through each of the records and wrap the data inside some HTML markup. You could replace the “Fetching Data…” text here with an animated pre-loader for something more visually appealing:

```javascript
return (
  <div>
    {recipes.length > 0 ? (
      recipes.map((record) => (
        <a href={record.fields.url} key={record.id}>
          <img src={record.fields.photo[0].url} alt={record.fields.recipe} />
          <p>{record.fields.recipe}</p>
        </a>
      ))
    ) : (
      <p>Fetching Data...</p>
    )}
  </div>
);
```

Finally load the component by modifying `App.js` as follows:

```javascript
import "./App.css";
import Recipes from "./Recipes";

function App() {
  return (
    <div className="App">
      <header className="App-header">
        <Recipes />
      </header>
    </div>
  );
}

export default App;
```

That’s all for this tutorial. Although this project was very basic it serves as a solid foundation for building more complex applications using React & Airtable. If you want to see the full capabilities of Airtable browse the [pre-built templates](https://airtable.com/templates) for inspiration.