about code ¯\_(ツ)_/¯

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.

Building a React app with multiple views

We’re gonna walk though building a React app like the Amazon app except here we have an app for looking though Minecraft games on iTunes. Let’s call it Minecraftazon.

iTunes Web

You might have heard the term Single Page App (SPA), technical that’s what we’re building here with React. Yes, I know it has multiple pages but those pages are not fetched from a server, it’s just React changing your apps view in the browser.

In React everything is a component

― Me

Since our app is one big component each page is just a child-component with it’s own set of child-components. And to the browser it’s just one HTML page that it loads hence the term Single Page App.

https://yourapp.com/

Let’s pretend the above url loads your app in a browser which lists some products. Now when the user clicks on a product you need the browser to navigate to the page for that specific product.

https:/yourapp.com/product/123

To achieve this in SPAs you need something called a Router. A router can artifically change the url the browser displays and also change the page displayed by your app. It is also just a component, but one that do everything you need in relation to navigating between pages.

There are many routers to choose from and arguments around each one, but you’ll pick the one called react-router. Yes, cause I said so 😀

yarn add --dev react-router

This will add react-router to your project. Remeber Yarn from the first getting started article.

...
import { BrowserRouter as Router, Route, Link } from 'react-router-dom'

const App = () => (
  <>
  <Link to='/product'>
    Home
  </Link>

  <Link to='/product/123'>
    Product 123 
  </Link>

  <Router>
    <>
    <Route exact path="/" component={HomePage} />
    <Route path="/product/:id" component={ProductPage} />
    </>
  </Router>
  </>
)
...

That’s all you need when the Link is clicked the Router switches to the selected page component.

This is not specific to a Router but if you’re wondering what <> and </> is, it’s called a React Fragment. Often in React a single child component is needed like with Router, you could use a div but using a fragment is better since it is not a real element and no extra element is added to your HTML.

const HomePage = () => (
  <h1>We're 🏚</h1>
)

const ProductPage = (props) => (
  <h1>Product Number ${props.match.params.id}</h1>
)

The component for a page is just another plain old component. If you need the id (or another value)) from the url path, you can find it under props.match.params.

SPA technical sidetrack

As browsers have gotten more and more sophisticated it’s now possible to build near desktop like experiences in them. Traditionally what would have taken an actual Mac or Windows apps to do can now be done in the browser.

There are pros and cons to building an SPA. Lets start with the cons – complicated, could be slower to load, might not be SEO friendly.

React helps reduce or remove these risks entirely. It makes SPAs easy to build, technology like code-splitting can make your app load faster, server-side rendering makes things search engine friendly. SPAs create a rich interactive experience, at this point all of the most popular apps in the world FB, Twitter, Linkedin, Google are SPAs.

I believe React + GraphQL can make it easier and faster to build a rich, interactive app with a smaller more user focused team.

The Minecraftazon app

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

import styled from 'styled-components'
import { BrowserRouter as Router, Route, Link } from 'react-router-dom'
import data from './data'

const Home = styled.div`
  display: flex;
  flex-wrap: wrap;
  padding: 10px;
  background-color: #111;

  & a { text-decoration: none; }
`
const GameItem = styled.div`
  padding: 30px;
  margin: 30px;

  text-decoration: none; 
  font-family: sans-serif;
  font-size: 20px;
  font-weight: 800;
  color: #fefefe;

  background-image: url(${props => props.image});
  border-radius: 0.5em;

  ...
`

const HomePage = (props) => (
  <Home>
  {data.map(v =>
      <Link to={`/game/${v.trackId}`} key={v.trackId} >
        <GameItem image={v.artworkUrl512}>
        <h1 className='name'>{v.trackName}</h1>
        </GameItem>
      </Link>
  )}
  </Home>
)

const Details = styled.div`
  display: flex;
  padding: 20px;
  height: 100%;
  
  border: 1px solid white;
  background-color: #111;

  color: #fefefe;
  font-family: sans-serif;

  ...
`

const DetailsPage = (props) => {
  let id = props.match.params.id
  let g = data.find(v => v.trackId == id)

  return (
  <Details>
  <img class="artwork" src={g.artworkUrl512}/>
  <div>
    <h1 class="title">{g.trackName}</h1>
    <p class="description">{g.description}</p>
    <div class="screenshots">
    {g.screenshotUrls.map(v => <img src={v} key={v} /> )}
    </div>
  </div>
  </Details>
  )
}

const App = () => (
  <Router>
    <>
    <Route exact path="/" component={HomePage} />
    <Route path="/game/:id" component={DetailsPage} />
    </>
  </Router>
)

ReactDOM.render(<App />, document.body);

There is a bunch of CSS that I’ve skiped over and replaced with . If you want to see all of that just download the project code and see it in there.

...
<div class="screenshots">
  {g.screenshotUrls.map(v => <img src={v} key={v} /> )}
</div>
...

This above piece of code might look a little confusing but what it’s doing is walking though (using map) a list of images inside of g.screenshotUrls. And for each image url it’s outputting a HTML img tag (using an arrow function) with it’s src set to the image url.

Also keep in mind in react when you have a list of elements each one needs a unique key defined. In this case we just use the same image url for the key, in other cases you might use a number.

What now?

I want to mention that the data for this app is in a file that’s part of it’s source code. Originally the data came from the iTunes API. And if this were a real production app then yes that data would have to be fetching when the app loads.

Fetching data from an API and using it within your React app is a little complicated and I’ll dedicate a seperate post to explaining it.

Well, by now you should know enough to get started hacking on your own app. Try and make your own personal website in React.

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.

$ git clone https://github.com/dosco/react-examples.git
$ cd react-examples/single-page-apps
$ 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.