DEV Community

Cover image for React Patterns: Local API
James Cox
James Cox

Posted on • Updated on

React Patterns: Local API

Introduction

I want to talk about a common pattern I use in my React apps to display common sets of data: hard-coding a "local API" into a project, via a local JSON file.

In my GIF FIT app all the exercises are a local JSON file that I import to one of my reducers and apply the selecting random exercises based on user input. I have a separate file for dumbbell exercises.

In my portfolio site I also have two different .json files, one for my projects and one for my blogs.

This article will explore what is an API and how I simulate using one in my projects.

API - What is it?

API is short for "Application Programming Interface". I could paste in a lot of technical definitions, but I would rather just summarize in my own words:

Think of an API as a way to define how information is both stored and then shared. Anytime you interact with a program, like Twitter or Facebook, any tweet you send or all the tweets you read, any terrible facebook post shared by your racist uncle that ends up in your feed, are all the processes of receiving data from and sending data to thier APIs.

APIs can follow different patterns, and some can be updated or modified by the user (like sending a new tweet, you just added an entry to Twitter's database) and some APIs are only meant to be consumed and not changed by the user.

How does this help us?

APIs make storing similar sets of data easy. Each Twitter user has the same properties: username, followers, tweets, likes, and A LOT MORE. Take a look at one Tweet object:

Example of a twitter object. It's scary!

!!!! That is intimidating even for me!

You can imagine how complex APIs can grow as the scale of the application grows.

Okay, now that we are thoroughly stressed out, take a breath, and relax.

We can recreate an API in our local files and use that data to call anywhere in our app. And trust me, you probably will not have to create anything that complex, at least not on your own! And if you do, you probably need to stop reading this article because you can control the Matrix.

Neo stopping bullets in the Matrix

How to make your local API

The first thing you want to do is figure out what you want to display.

I imbedded a (very contrived) Codesandbox that I created a for this DEV post, called Powerful People.

For each "Powerful Person" I wanted to display an image, their full name, their profession and their hobbies. Next I had to create the file for my local data. In my src folder I created a folder called data and inside that folder I create a file called personData.json.

src
└───data
│   │   personData.json
Enter fullscreen mode Exit fullscreen mode

What is JSON? It is short for "JavaScript Object Notation".

JSON is a text format that is completely language independent but uses conventions that are familiar to programmers of the C-family of languages, including C, C++, C#, Java, JavaScript, Perl, Python, and many others. These properties make JSON an ideal data-interchange language.

JSON is built on two structures:

A collection of name/value pairs. In various languages, this is realized as an object, record, struct, dictionary, hash table, keyed list, or associative array.
An ordered list of values. In most languages, this is realized as an array, vector, list, or sequence.

When we create a .json file we can only structure the data within in a very particular format: an array of objects. When we import our personData.json into our component, we will map through the array of objects, displaying each one individually. We will define each object with the properties I stated I wanted to display above.

Take a look at the structure of my "person object".

[
  {
    "id": 1,
    "url": "",
    "name": "",
    "role": "",
    "hobbies": [

    ]
  }
]
Enter fullscreen mode Exit fullscreen mode

A couple notes:

  • Each object SHOULD have an "id" property. When I have multiple .json files, I begin each array starting from a separate "hundred". This one starts at the "zero" hundred (001, 002) and a different .json file would have started with 201, 202, 203,
    etc.). I think this is good practice.

  • It's a VERY good idea to have separate a .json file with an empty object for quick and easy copy-and-pasting new entries into your array. I call mine structure.json.

src
└───data
│   │   personData.json
│   │   structure.json
Enter fullscreen mode Exit fullscreen mode

Check out my personData.json file with a couple entries filled out. Not too bad, huh! Each object gets a unique "id" and you just fill out what you want. This has numerous benefits that I will touch later as we get to displaying the information on screen!

[
  {
    "id": 1,
    "url": "https://cdn.vox-cdn.com/thumbor/w4zoPhL-LTUszPWHAUOeCmyS07w=/366x80:1263x685/1200x800/filters:focal(634x212:896x474)/cdn.vox-cdn.com/uploads/chorus_image/image/67233661/Ef4Do0cWkAEyy1i.0.jpeg",
    "name": "Bruce Wayne",
    "role": "Batman",
    "hobbies": [
      "spelunking",
      "stalking",
      "beating up bad guys"
    ]
  },
  {
    "id": 2,
    "url": "https://images2.minutemediacdn.com/image/fetch/w_736,h_485,c_fill,g_auto,f_auto/https%3A%2F%2Fwinteriscoming.net%2Ffiles%2F2018%2F11%2FGaladriel.jpg",
    "name": "Lady Galadriel",
    "role": "Ring Bearer",
    "hobbies": [
      "giving gifts",
      "star gazing",
      "slaying orcs"
    ]
  }
]
Enter fullscreen mode Exit fullscreen mode

And the data can be anything you want or need it to be! Check out a couple of .json examples from other React projects:

portfolio site blogs

[
    {
        "id": 201,
        "logo": "devto.png",
        "name": "React Hooks Series: useState",
        "image": "useState screenshot.jpg",
        "summary": "Part one in my React Hooks Series. I examine the useState hook in a basic timer app with examples from Codesandbox.",
        "url": "https://dev.to/jamesncox/react-hooks-series-usestate-12ne"
    },
    {
        "id": 202,
        "logo": "devto.png",
        "name": "React Hooks Series: useEffect",
        "image": "useEffect screenshot.jpg",
        "summary": "Part two in my React Hooks Series takes a look at the useEffect hook and how I implememnt in a small timer app I created in Codesandbox.",
        "url": "https://dev.to/jamesncox/react-hook-series-useeffect-in2"
    }
]
Enter fullscreen mode Exit fullscreen mode

portfolio site projects

[
    {
        "id": 1,
        "name": "GIF FIT",
        "image": "gif fit resized collage.jpg",
        "github": "https://github.com/jamesncox/gif-fit",
        "url": "https://gif-fit.netlify.app/",
        "summary": "Home workouts made easy!",
        "description": "Gif Fit builds randomized workouts for you that you can do without any equipment in your home. Select how many exercises you want to perform, how long each one lasts, the rest period in between and total number of rounds. Gif Fit will keep track of each move for you and let you know when to rest and prepare for the next exercise. Features a React front-end, Redux to manage state, and Material UI for styling. Gifs are sourced from Giphy.com (special thanks and credit to 8fit for uploading so many awesome exercises). Made with love to genuinely help others during these stressful and challenging times.",
        "technologies": [
            "React",
            "JavaScript",
            "Redux",
            "Material UI"
        ]
    },
    {
        "id": 2,
        "name": "DO DID DONE",
        "image": "do did done collage.jpg",
        "github": "https://github.com/jamesncox/do-did-done-react",
        "url": "https://do-did-done.netlify.app/",
        "summary": "Keep track of your todos by category",
        "description": "Do Did Done allows a user to create an account and select several categories to manage their tasks. Do Did Done is made with a React frontend and a Rails API backend. The React frontend features Material UI components, React router, Redux and local state management, functional components and React hooks and a thoughtful design for improved UI and UX. The frontend consumes the Rails API with full CRUD functionality. The Rails API backend is hosted on Heroku and features a PostgreSQL database. It handles sessions, cookies, CRUD functionality, separation of concerns and MVC structure.",
        "technologies": [
            "React",
            "Rails",
            "JavaScript",
            "Redux"
        ]
    }
]
Enter fullscreen mode Exit fullscreen mode

YES. You have create the array of objects, and hard-code all this data in yourself. BUT! You would have to do that ANYWAY in your HTML/JSX, creating a separate <div> for each entry. Trust me, this way seems like more work now, but it saves you so much time later.

Time to use your data

We have come to the fun part: USING our local API!

Because this is a very basic and contrived example, I kept my app to one component: App.js. Let's import our data.

import PersonData from './data/personData'
Enter fullscreen mode Exit fullscreen mode

And when we console.log(PersonData)

[Object, Object, Object, Object, Object, Object, Object]
   0: Object
   id: 1
   url: "https://cdn.vox-cdn.com/thumbor/w4zoPhL-LTUszPWHAUOeCmyS07w=/366x80:1263x685/1200x800/filters:focal(634x21 
   2:896x474)/cdn.vox-cdn.com/uploads/chorus_image/image/67233661/Ef4Do0cWkAEyy1i.0.jpeg"
   name: "Bruce Wayne"
   role: "Batman"
   hobbies: Array[3]
1: Object
2: Object
3: Object
4: Object
5: Object
6: Object

Enter fullscreen mode Exit fullscreen mode

Nice! We have access to the beautiful JSON that we made ourselves. Awesome!

Time to display those objects on the screen.

Our entire App component:

import React from "react";
import "./styles.css";
import "./responsive.css"
import PersonData from './data/personData'

export default function App() {
  return (
    <div className="App">
      <h1>Powerful People</h1>
      {PersonData.map(person => {
        return (
            <div className="card" key={person.id}>
              <div className="row">
                <div className="column">
                  <div>
                    <img src={person.url} alt={person.name} />
                  </div>
                </div>
                <div className="column">
                <div className="info">
                  <p>Full name</p>
                  <h4>{person.name}</h4>
                  <p>Profession</p>
                  <h4>{person.role}</h4>
                  <p>Hobbies</p>
                  <ul>
                    {person.hobbies.map((hobby, i) => { 
                      return(     
                        <li key={i}>{hobby}</li>
                      )
                    })}
                  </ul>
                </div>
              </div>
            </div>
            </div>
            )
        })}
    </div>
  )
}
Enter fullscreen mode Exit fullscreen mode

You can see that inside our {PersonData.map(person => { we access each object's properties: person.name, person.role, and then map again through each objects hobbies:

<ul>
  {person.hobbies.map((hobby, i) => { 
     return(     
        <li key={i}>{hobby}</li>
     )
   })}
</ul>
Enter fullscreen mode Exit fullscreen mode

Some notes:

  • Each object in a list must have a unique key or the linter gets mad at you. This is why we give each object an "id" property in our JSON
<div className="card" key={person.id}>
Enter fullscreen mode Exit fullscreen mode

and

<li key={i}>{hobby}</li>
Enter fullscreen mode Exit fullscreen mode

Where i is the index for each hobby and sufficient to be a unique key.

  • We only had to create ONE <div className="card">. If we were not using our local data from personData.json, we would have to create a separate div for EACH person we wanted to display on the screen. Imagine how out of control that could get! AND if you want create another person, you simply create another entry in personData.json and VOILA! It's on the screen!

It's basically
Magic gif

Wrapping up

I recognize we could argue the semantics of is a local .json file really an API, because you don't really communicate with it. BUT I don't care! I believe this is an EXCELLENT way to introduce yourself the concept of APIs and how to begin utilizing the JSON structure in your apps.

Learning how to communicate with an external API is a seperate article for another day.

However, if you are comfortable not only writing your own JSON, but mapping through it and extracting it's properties, when you start to communicate with external APIs, you will be in a GREAT spot to getting that data on your screen.

As always, thank you so much for reading my posts. I appreciate you taking time to engage with my thoughts and opinions. I welcome your feedback and if you're in the mood, PRAISE FOR MY GENIUS.

Just kidding...

Until next time, HAPPY CODING!

Top comments (1)