How to Create a Reddit Clone Using React and Firebase

React is an awesome JavaScript library for building user interfaces. Since the publishing of Create React App, it has become very easy to scaffold a barebones React application.

In this article, we will be using Firebase along with Create React App to build an app which will function similar to Reddit. It will allow the user to submit a new link which can then be voted on.

Here’s a live demo of what we’ll be building.

Why Firebase?

Using Firebase will make it very easy for us to show real-time data to the user. Once a user votes on a link, the feedback will be instantaneous. Firebase’s Realtime Database will help us in developing this feature. Also, it will help us to understand how to bootstrap a React application with Firebase.

Why React?

React is particularly known for creating user interfaces using a component architecture. Each component can contain internal state or be passed data as props. State and props are the two most important concepts in React. These two things help us determine the state of our application at any point in time. If you are not familiar with these terms, please head over to the React docs first.

Note: You can also use a state container like Redux or MobX, but for the sake of simplicity, we won’t be using one for this tutorial.

The whole project is available on Github.

Setting up the project

Let’s walk through the steps to set up our project structure and any necessary dependencies.

Installing create-react-app

If you haven’t already, you need to install create-react-app. To do so, you can type the following in your terminal:

npm install -g create-react-app

Once you’ve installed it globally, you can use it to scaffold a React project inside any folder.

Now, let’s create a new app and call it reddit-clone.

create-react-app reddit-clone

This will scaffold a new create-react-app project inside the reddit-clone folder. Once the bootstrapping is done, we can go inside reddit-clone directory and fire up the development server:

npm start

At this point, you can go to http://localhost:3000/ and see your app skeleton up and running.

Structuring the app

For maintenance, I always like to separate my containers and components. Containers are the smart components which are contains the business logic of our application and manage Ajax requests. Components are simply dumb presentational components. They can have their own internal state which can be used to control the logic of that component (e.g. showing the current state of a controlled input component).

After removing the unnecessary logo and css files, this is how your app should look like now. We created a components folder and a containers folder. Let’s move App.js inside the containers/App folder and create registerServiceWorker.js inside the utils folder.

Structuring the app

Your src/containers/App/index.js file should look like this:

// src/containers/App/index.js

import React, { Component } from 'react';

class App extends Component {
  render() {
    return (
      <div className="App">
        Hello World
      </div>
    );
  }
}

export default App;

Your src/index.js file should look like this:

// src/index.js

import React from 'react';
import ReactDOM from 'react-dom';
import App from './containers/App';
import registerServiceWorker from './utils/registerServiceWorker';

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

Go to your browser and if every thing works fine you will see Hello World on your screen.

You can check my commit on Github.

Adding react-router

React-router will help us define the routes for our app. It’s very customizable and very popular in the react ecosystem.

We will be using version 3.0.0 of react-router.

npm install --save react-router@3.0.0

Now, add a new file routes.js inside the src folder with the following code:

// routes.js

import React from 'react';
import { Router, Route } from 'react-router';

import App from './containers/App';

const Routes = (props) => (
  <Router {...props}>
    <Route path="/" component={ App }>
    </Route>
  </Router>
);

export default Routes;

The Router component wraps all the Route components. Based on the path prop of the Route component, the component passed to the component prop, will be rendered on the page. Here, we are setting up the root URL (/) to load our App component using the Router component.

<Router {...props}>
  <Route path="/" component={ <div>Hello World!</div> }>
  </Route>
</Router>

The above code is also valid. For the path /, the <div>Hello World!</div> will be mounted.

Now, we need to call our routes.js file from our src/index.js file. The file should have the following content:

// src/index.js

import React from 'react';
import ReactDOM from 'react-dom';
import { browserHistory } from 'react-router';

import App from './containers/App';
import Routes from './routes';
import registerServiceWorker from './utils/registerServiceWorker';

ReactDOM.render(
  <Routes history={browserHistory} />,
  document.getElementById('root')
);

registerServiceWorker();

Basically, we are mounting our Router component from our routes.js file. We pass in the history prop to it so that the routes know how to handle history tracking.

You can check my commit on Github.

Adding Firebase

If you don’t have a Firebase account, create one now (it’s free!) by going to their website. After you’re done creating a new account, log into your account and go to the console page and click on Add project.

Enter the name of your project (I’ll call mine reddit-clone), choose your country, and click on the Create project button.

Now, before we proceed we need to change the rules for the database since, by default, Firebase expects the user to be authenticated to be able to read and write data. If you select your project and click on the Database tab on the left, you will be able to see your database. You need to click on the Rules tab on the top that will redirect us to a screen which will have the following data:

Continue reading %How to Create a Reddit Clone Using React and Firebase%


Source: Sitepoint