Real-time Code Sharing Application Using React and Firebase Part-2

Saad Hassan
4 min readNov 24, 2018

Implementing React Router for Navigation and Code Mirror Editor

Previous Post: Part-1: Creating Simple React App and Deploying it on Firebase

Now we know how to deploy our app to firebase lets move on creating basic UI and structure for the app. First, we will be needing a package that would help in navigation through our SPA (Single Page App). We will be using React Router which consists of basic navigational components. Let’s install the package.

npm install -S react-router-dom

Structuring our Code

src/
components/
Header.js
... DumbComponents.js
containers/
App/
App.js
App.router.js
App.css
Pages/
Home.js
Home.css
Coding.js
Coding.css
... SmartComponents.js
index.js
index.css
...
.

Lets first make Header component and save that in components folder. component folder will container dumb-components. These are "presentational" components whose responsibility is to simply present something to the DOM. These don't have internal state and they don't require to modify the data they are presenting. Normally UI Elements like Header, Custom Buttons, Switches, Tables etc. are made dumb-components.

import React from "react";
import { Link } from "react-router-dom";
// You can use "type" which will help in intellisense in IDE'stype Props = {
style: React.CSSProperties,
extras: React.ReactHTML
};
const Header = (props: Props) => {
return (
<header style={props.style} className="App-header">
<Link className="App-title" to="/">Realtime Code Share</Link>
<div className="extras">{props.extras}</div>
</header>
);
};
export default Header;/* App.css */.App-header {
background-color: rgb(0, 0, 0);
height: 80px;
display: flex;
align-items: center;
color: white;
padding: 0px 64px;
}
.App-header .extras {
margin-left: auto;
}
.App-title {
color: #fff;
font-size: 18px;
font-weight: 700;
line-height: 36px;
text-decoration: none;
}
.App-title:active, .App-title:hover {
color: #fff;
}

After creating Header lets now create our routes. We will create routes which I normally store in pages in containers folder that will contain smart components and pages. We will be requiring two route pages one for Home and other the coding ground. So let's create Home and Coding Pages.

// containers/pages/Home.jsimport React from "react";
import { Link } from "react-router-dom";
import Header from "../../components/Header";
export default class HomePage extends React.Component {
render() {
return (
<React.Fragment>
<Header />
<div className="homepage">
<p className="title">
Share Code with in <span className="highlight">Realtime</span>.
<br />
Anywhere, Anytime and with <span className="highlight">Anyone</span>
.
</p>
<p className="sub-title">
Simple Realtime Code Sharing Editor App. Using Firebase Realtime
Database and Code Mirror as Editor.
</p>
<div>
<Link className="btn" to="/sad">
Share Code
</Link>
</div>
</div>
</React.Fragment>
);
}
}
/* App.css */.homepage {
display: flex;
padding: 0px 64px;
justify-content: center;
flex-direction: column;
height: calc(100vh - 80px);
}
.title {
font-size: 36px;
font-weight: 100;
margin-bottom: 12px;
}
.sub-title {
font-size: 16px;
font-weight: 700;
color: rgb(124, 124, 124);
margin-bottom: 36px;
max-width: 500px;
}
.highlight {
color: #5ce198;
}

React Router provides Link component that we will use instead of <a /> anchor tags for navigating between pages and contents. Though you can always use <a/> but it will reload whole page which may not be necessary always. <Links /> would help to prevent it.

For Coding Ground Page we will be needing text-editor that would help in editing code. I came across CodeMirror which provides quite functionalities when it comes to code editing. It's implemented in JavaScript and we will be needing Wrapper for React and thankfully there is a component for it implemented by JedWatson. So lets install the component and create Coding.jspage in pages folder.

npm install -S react-codemirrorimport React from "react";
import Header from "../../components/Header";
import CodeMirror from "react-codemirror";
require("codemirror/lib/codemirror.css");
require("codemirror/mode/javascript/javascript");
require("codemirror/theme/dracula.css");
export default class CodingPage extends React.Component {
state = {
code: '// Code Here'
};
render() {
return (
<React.Fragment>
<Header style={{ background: "#1d1f27" }} extras={<div>{Date()}</div>}/>
<div className="coding-page">
<CodeMirror
className="code-mirror-container"
value={this.state.code}
options={{
theme: "dracula",
lineNumbers: true,
mode: "javascript"
}}
/>
</div>
</React.Fragment>
);
}
}

For two way binding we will bind state with the value of CodeMirror. Also I have configured theme and default option of CodeMirror as per my likings. You can configure as per yours.

The <App>

Once the pages and components have been created lets configure our Router in App.js. <BrowserRouter> component expect to receive a single child element. The <BrowserRouter>should be used when you have a server that will handle dynamic requests. In our case firebase hosting can be configured for dynamic requests.

<Route> component is the component responsible for rendering your component. It handles url match and then renders the contents accordingly. There can be nested routes that define nested content on navigation changes. You can explore React Router Docs for more information on nesting routes.

// containers/App/App.jsimport React, { Component } from "react";
import { BrowserRouter as Router, Route, Link } from "react-router-dom";
import "./App.css";
import { HomePage, CodingPage } from "../pages/";
// import AppRouter from './App.router'
class App extends Component {
render() {
return (
<Router>
<div className="App">
{/* <AppRouter /> */}
<Route exact path="/" component={HomePage} />
<Route path="/:sessionid" component={CodingPage} />
</div>
</Router>
);
}
}
export default App;

You can also create router component if you have multiple routes and want clean and modular code. Just import that component and render inside Apps <div>.

:sessionid - defines url parameter which we will use for creating different coding grounds.

Hurray 🙌🎉 the basic structure is done.

We will now configure Firebase Realtime Database and Wire that with our app in Part-3 of this article.

  1. Part-1: Creating Simple React App and Deploying it on Firebase
  2. Part-2: Implementing React Router for Navigation and Code Mirror Editor
  3. Part-3: Wiring the app with Firebase Real-time Database

This post was first published on my blog.

--

--