Building Static Web Pages

Questions

  • What JavaScript libraries should I use to create a web pages?
  • How can I use them to create basic HTML elements?
  • How can I style those pages?
  • How can I mix my JavaScript with HTML?
  • How can I create reusable components for building web pages?
  • How can separate my code into multiple files to make it more manageable?

Introduction

FIXME-18: diagram

FIXME-18: diagram

Hello, World

<!DOCTYPE html>
<html>
  <head>
    <title>Hello React</title>
    <meta charset="utf-8">
    <script src="https://fb.me/react-15.0.1.js"></script>
    <script src="https://fb.me/react-dom-15.0.1.js"></script>
  </head>
  <body>
    <div id="app">
      <!-- this is filled in -->
    </div>
    <script>
      ReactDOM.render(
        React.DOM.h1(null, "Hello, React"),
        document.getElementById("app")
      )
    </script>
  </body>
</html>
  <body>
    <div id="app">
      <!-- this is filled in -->
    </div>
    <script>
      const attributes = {
        'style': {
          'background': 'pink',
          'font-style': 'italic'
        }
      }
      ReactDOM.render(
        React.DOM.h1(attributes, "Hello, world"),
        document.getElementById("app")
      )
    </script>
  </body>

JSX

<!DOCTYPE html>
<html>
  <head>
    <title>Hello World</title>
    <meta charset="utf-8">
    <script src="https://fb.me/react-15.0.1.js"></script>
    <script src="https://fb.me/react-dom-15.0.1.js"></script>
    <script src="https://unpkg.com/babel-standalone@6/babel.js"></script>
  </head>
  <body>
    <div id="app">
      <!-- this is filled in -->
    </div>
    <script type="text/babel">
      ReactDOM.render(
        <h1>Hello, world</h1>,
        document.getElementById("app")
      )
    </script>
  </body>
</html>
  <body>
    <div id="app">
      <!-- this is filled in -->
    </div>
    <script type="text/babel">
      const allNames = ['McNulty', 'Jennings', 'Snyder', 'Meltzer', 'Bilas', 'Lichterman']
      ReactDOM.render(
        <ul>{allNames.map((name) => { return <li>{name}</li> })}</ul>,
        document.getElementById("app")
      )
    </script>
  </body>

Creating Components

  <body>
    <div id="app">
      <!-- this is filled in -->
    </div>
    <script type="text/babel">
      const allNames = ['McNulty', 'Jennings', 'Snyder', 'Meltzer', 'Bilas', 'Lichterman']

      const ListOfNames = () => {
        return (<ul>{allNames.map((name) => { return <li>{name}</li> })}</ul>)
      }

      ReactDOM.render(
        <div>
          <ListOfNames />
        </div>,
        document.getElementById("app")
      )
    </script>
  </body>
  <body>
    <div id="app">
      <!-- this is filled in -->
    </div>
    <script type="text/babel">
      const allNames = ['McNulty', 'Jennings', 'Snyder', 'Meltzer', 'Bilas', 'Lichterman']

      const ListElement = (props) => {
        return (<li id="{props.name}"><em>{props.name}</em></li>)
      }

      ReactDOM.render(
        <div>
          <ul>{allNames.map((name) => { return <ListElement name={name} /> })}</ul>
        </div>,
        document.getElementById("app")
      )
    </script>
  </body>

Developing with a Server

#!/usr/bin/env bash
server_path=${PWD}/node_modules/.bin/http-server
cd $1 && ${server_path}
  "scripts": {
    "demo": "./bin/run-server",
    
  }
<!DOCTYPE html>
<html>
  <head>
    <title>Hello Separate</title>
    <meta charset="utf-8">
    <script src="https://fb.me/react-15.0.1.js"></script>
    <script src="https://fb.me/react-dom-15.0.1.js"></script>
    <script src="https://unpkg.com/babel-standalone@6/babel.js"></script>
    <script src="app.js" type="text/babel"></script>
  </head>
  <body>
    <div id="app">
      <!-- this is filled in -->
    </div>
  </body>
</html>
ReactDOM.render(
  <h1>Hello, separate</h1>,
  document.getElementById("app")
)
<!DOCTYPE html>
<html>
  <head>
    <title>Hello Separate</title>
    <meta charset="utf-8">
    <script src="https://fb.me/react-15.0.1.js"></script>
    <script src="https://fb.me/react-dom-15.0.1.js"></script>
    <script src="https://unpkg.com/babel-standalone@6/babel.js"></script>
    <script src="ListElement.js" type="text/babel"></script>
    <script src="app.js" type="text/babel"></script>
  </head>
  <body>
    <div id="app">
      <!-- this is filled in -->
    </div>
  </body>
const ListElement = (props) => {
  return (<li id="{props.name}"><em>{props.name}</em></li>)
}
const allNames = ['McNulty', 'Jennings', 'Snyder', 'Meltzer', 'Bilas', 'Lichterman']
ReactDOM.render(
  <ul>{allNames.map((name) => { return <ListElement name={name} /> })}</ul>,
  document.getElementById("app")
)

Challenges

Real Data

  1. Create a file called programmers.js that defines a list of JSON objects called programmers with firstName and lastName fields for our programmers. (You can search the Internet to find their names.)
  2. Load that file in your page like any other JavaScript file.
  3. Delete the list allNames from the application and modify it to use data from the list programmers instead.

Loading constant data like this is a common practice during testing.

Ordering

What happens if you change the order in which the JavaScript files are loaded in your web page? For example, what happens if you load app.js before you load ListElement.js?

Multiple Targets

What happens if your HTML page contains two div elements with id="app"?

Creating a Component for Names

Create a new React component that renders a name, and modify the example to use it instead of always displaying names in <li> elements.

Striping

Suppose we want to render every second list element in italics. (This would be a horrible design, but once we start creating tables, we might want to highlight alternate rows in different background colors to make it easier to read.) Modify the application so that even-numbered list elements are <li>{name}</li> and odd-numbered list elements are <li><em>{name}</em></li>. (You may want to use the fact that a map callback can have two parameters instead of one.)

Key Points

  • Older dynamic web sites generated pages on the server.
  • Newer dynamic web sites generate pages in the client.
  • React is a JavaScript library for client-side page generation that represents HTML elements as function calls.
  • React replaces page elements with dynamically-generated content in memory (not on disk).
  • React functions can be customized with elements.
  • JSX translates HTML into React function calls so that HTML and JavaScript can be mixed freely.
  • Use Babel to translate JSX into JavaScript in the browser.
  • Define new React components with a pseudo-HTML element and a corresponding function.
  • Attributes to pseudo-HTML are passed to the JavaScript function as a props object.
  • Use Node’s http-server to load scripts from files during development.