about code ¯\_(ツ)_/¯

Fetching Data in React

Every React app needs to work with remote data. In this article we’ll walk though how you can make your React components talk to APIs and work with data.

The Reddit Art app

We’re gonna walk though building a React app that fetching data from the Reddit Art sub-reddit (/r/Art) and renders it into a beautiful carousel.

Reddit Art

There are two options when you need to fetch data for your React app. The first going the traditional way, that is making a request to an HTTP URL (aka. API Endpoint). This is what we did in this example as it’s still the most popular way to do things. There’s usually an API endpoint available for all your needs from saving, deleting, updating and fetching data.

The new way to do fetch data is called GraphQL. It’s a special kind of API that gives React developers more control. Instead of one API endpoint per data type, in GraphQL you have only one API where you request for any type of data you need. It was invented by Facebook and while it’s what all the cool kids are doing, it’s still pretty complicated and not as popular. I feel it will only get more popular as the tooling improve and things get simpler.

$ yarn add --dev axios

We’re using a package called Axios to help with talking to remote APIs. Axios is the popular way to make HTTP requests to API endpoints and talk JSON with them.

...
import axios from 'axios';
...

class RedditArt extends React.Component {
  state = {
    images: []
  }

  componentDidMount() {
    axios.get(`https://reddit.com/r/Art.json`)
      .then(res => {
        const images = res.data.data.children.map(obj => obj.data.url);
        this.setState({ images });
      });
  }

  render = () => (
    <Carousel images={this.state.images} />
  )
}
...

While there is a lot more in the complete app, this is the part that we need to focus on. Remember stateful components, this is one.

I didn’t previously talk about the lifecycle of components. Like us they are born they growup and then they die. Ok, that sounds depressing. 😔

The life of a component is a little different they are created and then their funtions are called in the following order. This order below is for when a component is created. A different set of functions are called in a different order when the component is updated due to a property value changing or when it’s deleted.

  1. constructor()
  2. getDerivedStateFromProps()
  3. render()
  4. componentDidMount()

This is the reason we make the API call to fetch our art data inside componentDidMount that way we’re sure the component is ready.

axios.get(`https://reddit.com/r/Art.json`)
  .then(res => {
    const images = res.data.data.children.map(obj => obj.data.url);
    this.setState({ images });
  });

Here we use the get() function in axios to request data from https://reddit.com/r/Art.json this returns a huge blob of JSON formatted data representing the Art sub-reddit.

We use map() to extract only the image url’s and create a list of those then save it in the component state. That’s all we need, the Carousel component accepts this list of image urls from the state as it’s property. Once that list is fetched the property is updated the the images are rendered onto the browser.

import React from 'react';
import ReactDOM from 'react-dom'

import styled from 'styled-components'
import axios from 'axios';

const Img = styled.img`
  height: 1000px;
`

const CarouselWrap = styled.div`
  display: flex;
  flex-direction: row;
`

const Carousel = (props) => (
  <CarouselWrap>
    {props.images.map((img, i) => 
      <Img src={img} key={`img-${i}`} />
    )}
  </CarouselWrap>
)

class RedditArt extends React.Component {
  state = {
    images: []
  }

  componentDidMount() {
    axios.get(`https://reddit.com/r/Art.json`)
      .then(res => {
        const images = res.data.data.children.map(obj => obj.data.url);
        this.setState({ images });
      });
  }

  render = () => (
    <Carousel images={this.state.images} />
  )
}

const Banner = styled.h1`
  position: fixed;
  margin: 10px;
  padding: 8px;
  border-radius: 5px;
  background-color: #ffeb3b;
  color: #222;
`

const App = () => (
  <>
  <Banner>Reddit Art</Banner>
  <RedditArt />
  </>
)

ReactDOM.render(<App />, document.getElementById('app'));

Most everything you see in this app code should be familiar by now. We’ve learn’t all the concepts that went into creating this app before.

Try this example

I encourage you to try it on your own. It’s pretty cool to see it all come together and have a functioning React app that works with real world data.

$ git clone https://github.com/dosco/react-examples.git
$ cd react-examples/remote-data
$ yarn install
$ yarn start --open

Follow me at twitter.com/dosco

  • Getting started with React

    Getting started with anything new is hard. In the frontend development world things are always changing, and changing fast. We’re gonna cut though all the complexity and get you Ninja status asap.

  • Data and React components

    The post second in this series on React. We focus on how data flows in and out of a React component and how you can use this data to connect multiple components together to build an app.

  • Building larger apps in React

    Having multiple pages in an app is pretty common. Take for example the Amazon app which has products and when you click one you get a detailed look at it. You’re gonna need to know how to build a React app with multiple pages so follow along.

  • Fetching Data in React

    Every React app needs to work with remote data. In this article we’ll walk though how you can make your React components talk to APIs and work with data.

  • Common Frontend Concepts

    React and the rest of the frontend development world is full of new terms. Anyone new can quickly feel overwhealmed. I’m going to try and explain the most popular terms that you will come across when working with React. Think of this as a glossary of things you will come across.