blog

  • Home
  • blog
  • Build a Peer-to-Peer File Sharing Component in React & PeerJS

Build a Peer-to-Peer File Sharing Component in React & PeerJS

In this tutorial we’re going to build a file sharing app with PeerJS and React. I’ll be assuming that you’re a complete beginner when it comes to React so I’ll be providing as much detail as possible.

For you to have an idea of what we’re going to build, here are a couple of screenshots of what the app will look like. First, when the component is ready for use:

filesharer component ready to connect

And here’s what it looks like when the current user is already connected to a peer and the peer has shared some files with the user:

filesharer component with shared files

The source code for this tutorial is available on GitHub.

The Tech Stack

As mentioned earlier, the file sharing app is going to use PeerJS and React. The PeerJS library allows us to connect two or more devices via WebRTC, providing a developer-friendly API. If you don’t know what WebRTC is, it is basically a protocol that allows real-time communications on the web. On the other hand, React is a component-based view library. If you’re familiar with Web Components, it’s similar in the way that it gives you the ability to create custom standalone UI elements. If you want to dive deeper into this, I recommend reading ReactJS For Stupid People.

Installing the Dependencies

Before we start building the app, we first need to install the following dependencies using npm:

npm install --save react react-dom browserify babelify babel-preset-react babel-preset-es2015 randomstring peerjs

Here’s a brief description of what each one does:

  • react – the React library.
  • react-dom – this allows us to render React components into the DOM. React doesn’t directly interact with the DOM, but instead uses a virtual DOM. ReactDOM is responsible for rendering the component tree into the browser. If you want to dive in more into this, I recommend reading ReactJS|Learning Virtual DOM and React Diff Algorithm.
  • browserify – allows us to use require statements in our code to require dependencies. This is responsible for bringing all the files together (bundling) so it can be used in the browser.
  • babelify – the Babel transformer for Browserify. This is responsible for compiling the bundled es6 code to es5.
  • babel-preset-react – the Babel preset for all react plugins. It’s used for transforming JSX into JavaScript code.
  • babel-preset-es2015 – the Babel preset that translates ES6 code to ES5.
  • randomstring – generates random string. We’ll use this for generating the keys needed for the file list.
  • peerjs – the PeerJS library. Responsible for making connections and sharing files between peers.

Building the App

Now we’re ready to build the app. First let’s take a look at the directory structure:

-js
-node_modules
-src
    -main.js
    -components
        -filesharer.jsx
index.html
  • js – where the JavaScript files that will be bundled by Browserify are stored.
  • src – where the React components are stored. Inside, we have the main.js file in which we import React and the components used by the app. In this case we only have filesharer.jsx which contains the main meat of the app.
  • index.html – the main file of the app.

Index Page

Let’s start with the index.html file. This contains the default structure of the app. Inside the <head> we have the link to the main stylesheet and the PeerJS library. Inside the <body> we have the title bar of the app and the main <div> where we’ll append the React component that we create. Just before the closing <body> tag is the main JavaScript file of the app.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>React File Sharer</title>

    <link href="http://cdn.muicss.com/mui-0.4.6/css/mui.min.css" rel="stylesheet" type="text/css" />
</head>
<body>

    <div class="mui-appbar mui--appbar-line-height">
        <div class="mui-container">
          <span class="mui--text-headline">
            React FileSharer
          </span>
        </div>
    </div>
    <br />
    <div class="mui-container">
        <div id="main" class="mui-panel"></div>
    </div>

    <script src="js/main.js"></script>
</body>
</html>

Main JavaScript File

The src/main.js file is where we render the main component into the DOM.

First, we require the React framework, ReactDOM, and the Filesharer component.

var React = require('react');
var ReactDOM = require('react-dom');
var Filesharer = require('./components/filesharer.jsx');

Then we declare an options object. This is used to specify options for the Filesharer component. In this case we’re passing in the peerjs_key. This is the API key that you get from the PeerJS website so that you can use their Peer Cloud Service to set up peer-to-peer connections. In the case of our app, it serves as the middleman between the two peers (devices) that are sharing files.

var options = {
    peerjs_key: 'your peerjs key'
}

Next we define the main component. We do that by calling the createClass method of the React object. This accepts an object as its argument. By default, React expects a render function to be defined inside the object. What this function does is to return the UI of the component. In this case we’re simply returning the Filesharer component which we imported earlier. We’re also passing in the options object as a value for the opts attribute. In React these attributes are called props and they become available for use inside the component, kind of like passing in arguments to a function. Later on, inside the Filesharer component, you can access the options by saying this.props.opts followed by any property you wish to access.

var Main = React.createClass({
  render: function () {
    return <Filesharer opts={options} />;
  }
});

Get the reference of the main div from the DOM and then render the main component using ReactDOM’s render method. If you’re familiar with jQuery, this is basically similar to the append method. So what we’re doing is appending the main component into the main div.

var main = document.getElementById('main');

ReactDOM.render(<Main/>, main);

Filesharer Component

The Filesharer component (src/components/filesharer.jsx), as I mentioned earlier, contains the main meat of the app. The main purpose of components is to have standalone code that can be used anywhere. Other developers can just import it (like we did inside the main component), pass in some options, render it and then add some CSS.

Breaking it down, we first import the React framework, randomstring library, and the PeerJS client.

var React = require('react');
var randomstring = require('randomstring');
var Peer = require('peerjs');

We expose the component to the outside world:

module.exports = React.createClass({
    ...
});

Earlier in our main JavaScript file we passed in an optional prop to customize the labels that will be shown in the file sharer component. To ensure that the correct property name (opts) and data type (React.PropTypes.object) are passed to the component, we use propTypes to specify what we’re expecting.

Continue reading %Build a Peer-to-Peer File Sharing Component in React & PeerJS%

LEAVE A REPLY