CS142 Project 4: Page Generation with ReactJS
Due: Thursday, May 2, 2019 at 11:59 PM
Setup
You should already have installed Node.js and the npm package manager your system. If not, follow the installation instructions now.
Create a directory project4 and extract the contents of
this zip file into the directory. The zip file contains the starter files for this assignment.
This assignment requires many node modules the contains the tools
(e.g. Webpack,
Babel,
ESLint) needed to build a
ReactJS web application as well as
a simple Node.js web server (ExpressJS)
to serve it to your browser. These modules can be fetch by
running the following command in the project4 directory:
npm installThe command will fetch around 600 node modules using around 110 megabytes of space into the subdirectory
node_modules.
We can use npm to run the various tools we had it fetch. As can be
seen in the "scripts" property of the package.json file, the
following run commands are availble:
npm run lint- Runs ESLint on all the project's JavaScript files. The code you submit should run EShint without warnings.npm run build- Runs Webpack using the configuration filewebpack.config.jsto package all of the projects JSX files into a single JavaScipt bundle in the directorycompiled.npm run build:w- Runs Webpack like the "run build" command except it invokes webpack with --watch so it will monitor the React components and regenerates the bundle if any of them change. This option is useful for development so changes made to components can be picked up by simply refreshing the browser to load the newly updated bundle. Otherwise you need to remember to run "npm run build" after every change.
Your solutions for all of the problems below should be implemented in the project4 directory.
This project uses ReactJS, a popular framework for building web applications. The project's goal is to get you enough up to speed with ReactJS and the cs142's coding conventions that you will be able to build a web application with it in the next project.
In order to fetch our web app via the HTTP protocol, we use a simple Node.js
web server that can be started with the command from the project4 directory:
node webServer.js
All the files in the project4 can be fetched using an URL starting with
http://localhost:3000. Click on
http://localhost:3000 to verify your
web server is running. It should serve the file index.html to your browser.
We recommend you configure you development environment to run webpack in watch mode so you will need to run the node web server and webpack when building and testing your project. You could do this by running the programs in different command line windows. Syntax errors get detected and reported by Babel so the output of webpack is useful. If you are running on a system with a unix-like shell like MacOS. The command:
node webServer.js & npm run build:wruns the web server in background and the webpack in forground within a single window.
Getting Started
In this project we require that you use the model, view, controller pattern described in class. There are many ways of organizing code under this pattern so we provide an example that both demonstrates some basic ReactJS features as well as showing the file system layout and module pattern we would like you to follow in your projects.
You should start by opening the example in your browser by navigating to the URL
http://localhost:3000/getting-started.html.
The page displays examples of ReactJS in action. The HTML in getting-started.html provides
a div for ReactJS to draw the app into and a script tag include the app's JavaScript bundle
compiled/gettingStarted.bundle.js. The webpack config
file webpack.config.js
directs that this bundle be created from the ReactJS file gettingStarted.jsx, a JSX
program that renders the ReactJS component named Example into the div in getting-started.html.
To support reusable components, we adopt a file organization that co-locates the ReactJS
component and its associated CSS stylesheet in a subdirectory of a directory
named components. The Example component is located
in the files components/example/{Example.jsx,Example.css}.
getting-started.html, gettingStarted.jsx,
components/example/{Example.jsx) since it shows the JavaScript
and JSX statements needed to run an ReactJS web application along with
explanatory comments. You should use this
pattern and file naming convention for the other components you build for the class.
Model data is typically fetched from the web server which retrieves the data from a database.
To avoid having to setup a database for this project we will give you an HTML script tag
to load the model data directly into the browser's DOM from the local file system.
The models will appear in the DOM under the property name cs142models. You will be
able to access it under the name window.cs142models in an ReactJS componment.
Problem 1: Understand and update the example view (5 points)
You should look through and understand the getting-started.html view
and the Example component. To demonstrate your understanding do the
following:
- Update the model data for the Example component to use your name rather than "Unknown name". You should find where "Unknown name" is and replace it.
-
Replace the contents of the
divregion with the classmotto-updatein the Example component with some JSX statements that displays your name and a short (up to 20 characters) motto. Like the user's name, the initial value for motto should come in with the model data. You must include some styling for this display inExample.css. - Extend the display you did in the previous step so it allows the user to update the motto being displayed. The default value should continue to be retrived from the model data.
Problem 2: Create a new component - states view (10 points)
Create a new component view that will display the names of all states containing a given substring. Your view must implement an input field which accepts a substring. The view will display in alphabetical order a list of all states whose names contain the given substring (ignoring differences in case). For example, the view for the substring of "al" should list the states Alabama, Alaska, and California. The page should also display the substring that was used to filter the states. If there are no matching states then the web page should display a message indicating that fact (rather than just showing nothing). All states should be displayed when the substring is empty.
As in Problem #1 we provide you the model data with states. It can
be accessed via window.cs142models.states after it is included with:
<script src="modelData/states.js"></script>
See states.js for a description of the format of the states data.
To help you get started and guide you to the file naming conventions we
want you to use we provided a file p2.html that will load
and display the bundle compiled/p2.bundle.js which
is generated by webpack from p2.jsx which displays
the React component States.
You can open this file in your browser via
the URL http://localhost:3000/p2.html.
The files you will need to implement are:
components/states/States.jsx- The ReactJS Component of your states component.-
components/states/States.css- Any CSS styles your component needs. You must include some styling for your state list here.
Problem 3: Personalizing the Layout (5 points)
Create a ReactJS component named Header that will display a personalized
header at the top of a view. Add this header to all ReactJS
web apps in your assignment (gettingStarted.jsx, p2.jsx,
p4.jsx, p5.jsx).
This header is in addition to the header from part 1 - do not
replace that header.
Use your imagination and creativity to
create a header that is "uniquely you". This can include additional images,
graphics, whatever you like. You can extend the JSX/JavaScript in the
components but you may not use external ReactJS Components or JavaScript
libraries such as JQuery. Be creative!
The files you will need to implement are:
components/header/Header.jsx- The ReactJS Component of your header component. This is defined a class Header of type React.Component.components/header/Header.css- Any CSS styles your component needs. You must include some styling for your header here.
gettingStarted.jax should have 2 headers: the
personalized header from Problem 3 at he top of the page and the header
with the motto from Problem 1.2 right below it. All other pages views
(p2.html, p4.html and p5.html)
should only have your personalized header from Problem 3.
Problem 4: Add dynamic switching of the views (10 points)
Create a p4.html and a corresponding JSX file
p4.jsx
that includes both view components
(the Example and States components). The
p4.jsx needs
to implement an ability to switch between the display of the two components.
When a view is displayed there should be a button above it that switches
to display the other view. For example, when the States view
is displayed the button above it should read "Switch to Example," and when
pushed the States should disappear and the Example
view should be displayed.
For this problem you will need to create the files above as well as
modify the webpack configuration file webpack.config.js
to build a file compiled/p4.bundle.js that you can
uses in p4.html file. Note that if you are using Webpack with
--watch (i.e. npm run build:w), you will need to restart it after
changing code>webpack.config.js.
Problem 5: Single page app (5 points)
Although the approach taken in Problem 4 allows you to switch between the two views, it does not allow you to bookmark or share a URL pointing at a particular view. Even doing a browser refresh event causes the app to lose track of which view was being displayed.
We can address this deficiency by storing the view information into the URL.
React Router provides
this functionality for ReactJS. For this problem make a
copy of your p4.html solution into a file named p5.html
and copy your p4.jsx into a file named p5.jsx.
Convert the code to use React Router
to switch between the two component views. You should have a styled toolbar-like
control (simple plain text links are not sufficient)
that will allow the user to switch between the example and states
component views.
Since this is the first extensions from the core ReactJS we import, we provide you with step-by-step instructions.
- The project's
package.jsonspecifies react-router so the npm install command already fetched it for us. We do need to explicitly import it into ourp5.jsxfile. Add the following import line:import { HashRouter, Route, Link } from "react-router-dom";The line uses the JavaScript import statement to bring in the ReactJS components from React Router: HashRouter , Route , and Link . The HashRouter module of React Router uses the fragment portion of the URL for storing infomation. So we can makep5.html#/statesmark showing the States view whilep5.html#/examplespecifies the Example component view. -
The most common way of using React Router is to conditially render
the view we want based on the current URL. It is
the
Route
component that implements this condition rendering when placed inside
a HashRouter element like:
<HashRouter> ... <Route path="/states" component={States} /> <Route path="/example" component={Example} /> ... </HashRouter>which would render the States component if the URL had#/statesand the Example component if the URL had#/example. -
Although we could use hyperlinks (i.e. <a tags) to switch views
react router recommends using the Link component to generated the
hyperlinks.
<Link to="/states">States</Link>
generates a hyperlink with href="#/states" and the strings "States" in it.
Style (5 points)
These points will be awarded if your solutions have proper MVC decomposition and follow the style guidelines discussed in lecture and section. Note that you should not directly manipulate the DOM in your code. In addition, your code and templates must be clean and readable. Remember to run ESLint before submitting. ESHint should raise no errors.
Deliverables
After implementing part 5, make sure parts 1 through 4 still work!
Use the standard class submission mechanism
to submit the entire application (everything in the project4
directory).