Learn how to build a sub-reddit website using Create React App and the Reddit API. You'll learn how to fetch from an API and a little React.

Building A Sub-Reddit App With React | A React Tutorial

Learn how to build a sub-reddit website with Create React App and the Reddit API.

For this tutorial I'm going to assume you have a basic understanding of HTML, CSS, and JavaScript, although you should have no problem following along without it. 

To start, you're going to need to install Node.js version 8.10 or higher and NPM version 5.6 or higher. You can do so by going to Node's website and installing the latest LTS release. That will download a file for you. Just click it and choose all of the defaults. It will automatically install NPM for you as well.

Now that you have both Node and NPM installed you should be able to type the following commands which will do three things for you.

  1. It will create a React boilerplate application for you using Facebook's Create React App
  2. It will change your directory into the folder you created (in this case I called it "my-app").
  3. And the final line will start the application for you.
npx create-react-app my-app
cd my-app
npm start

After running these commands this is what my text editor looks like. You can see the folder tree on the left. All I've done is open the file we'll be working with, "App.js", which is inside of the "src" folder.

undefined

You should also see the app running in your browser from the "npm start" command that you ran.

So the first thing we're going to do is to remove everything inside the header tags. Then, we're going to remove the import on line 2. After that you can type whatever you want you app to be called in between the header tags. You're App.js file should look something like this:

import React from 'react';
import './App.css';

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

export default App;

Before we retrieve any data from Reddit lets change a little CSS so that our header takes up less space. Inside the src folder there is a App.css folder. Open that and inside the `App.header` class change the min-height property to be 100px instead of 100vh.

Next, we need to retrieve some data from Reddit. To do so we're going to have to use Reacts componentDidMount life-cycle method to call a function that will make an API request for us. So we need to change our React component a bit from a function to a class. Lets do that now.

import React from 'react';
import './App.css';

class App extends React.Component {
  componentDidMount() {
    // we'll make the API request here
  }

  render() {
    return (
      <div className="App">
        <header className="App-header">
          Big Brain App
        </header>
      </div>
    );
  }
}

export default App;

Now we can add in the function as it's also know, a Web API called the Fetch API. I've attached a link so you can read more about it if you're interested. But, the basic usage is pretty simple. We're going to make a request to a specific URL (https://www.reddit.com/r/christianmemes.json) that will give use back a JSON blob containing a bunch of useful data for the sub-reddit `r/christianmemes` (my favorite sub-reddit lol).

Let's now write out what that request will look like.

componentDidMount() {
  fetch("https://www.reddit.com/r/christianmemes.json")
    .then(res => res.json())
    .then(res => {
      console.log(res);
    })
}

Let's go through what's happening. We're sending a request to reddit and the first call to fetch returns a promise which resolves to the Response class. We can then call the .json() function on the response class which returns the response as a JSON object and that is what is passed into the second promise. There we console.log the JSON to see what we have. In your browser you can see what was logged by right clicking anywhere on the website you've created and clicking the console tab. 

Now we're currently only logging the data we get back and not actually doing anything with it, so lets display something. To do so, we'll need to store the response we get back in the state of our app.

state = {
  data: null,
};

componentDidMount() {
  fetch("https://www.reddit.com/r/christianmemes.json")
    .then(res => res.json())
    .then(res => {
      console.log(res);
      this.setState({
        data: res.data,
      });
    })
}

Above the componentDidMount life-cycle method we've initialized the initial state of the application to contain a data property set to null. The application will work without initializing the state to null, but it's good practice to define your state before you use the setState method. 

Now that we've set the state of our application to be the data we retrieved from Reddit we can display what we've retrieved on our own web app! If you'd like to check that the state was set properly you can write `console.log(this.state.data)` directly after the call to this.setState().

Now lets add some pictures of memes to our web app.

If you take a look at the state you'll see that we have an array of 25 Reddit posts. Each one containing it's own data property with a title and an image url property of it's own. Keep in mind that the url property will not always contain something, but it's good enough for this.

You can render these posts by changing the render method in the following way:

render() {
  const { data } = this.state;
  return (
    <div className="App">
      <header className="App-header">
        Big Brain App
      </header>

      <div>
        {data && data.children.map(function(child) {
          return (
            <div>
              <h3>{child.data.title}</h3>
              <img alt="Meme" src={child.data.url} />
            </div>
          )
        })}
      </div>
    </div>
  );
}

Here we've de-structured the state object into a data variable. We then check to see if data is available and if it is we map over the children array. For each child we return a some React which contains the properties of our child. 

That's basically it. You can add some CSS to make the memes look better and if you'd like a tutorial on CSS or more React stuff please let me know in the comments. Also, don't hesitate to ask if I left anything unexplained. 

Comments
Authors profile

Jonathan Emig

Subscribe for monthly technical content

* indicates required