$35
CS142 Project 4: Page Generation with ReactJS
Setup
You should already have installed Node.js and the npm package manager your system. If not, follow the installation instructions (install.html) now.
Create a directory project4 and extract the contents of this zip le (downloads/project4react.zip) into the directory. The zip le contains the starter les for this assignment.
This assignment requires many node modules the contains the tools (e.g. Webpack (https://webpack.js.org/), Babel (https://babeljs.io/), ESLint
(https://eslint.org/)) needed to build a ReactJS (https://reactjs.org/) web application as well as a simple Node.js web server (ExpressJS
(http://expressjs.com/)) to serve it to your browser. These modules can be fetch by running the following command in the project4 directory:
The 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 le, the following run commands are availble:
npm run lint - Runs ESLint on all the project's JavaScript les. The code you submit should run ESLint without warnings.
npm run build - Runs Webpack (https://webpack.js.org/) using the con guration le webpack.config.js to package all of the projects JSX les
into a single JavaScipt bundle in the directory compiled .
npm run build:w - Runs Webpack (https://webpack.js.org/) like the "run build" command except it invokes webpack with --watch
(https://webpack.js.org/api/cli/#watch-options) 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 (https://reactjs.org/), 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:
All the les in the project4 can be fetched using an URL starting with http://localhost:3000 (http://localhost:3000). Click on http://localhost:3000 (http://localhost:3000) to verify your web server is running. It should serve the le index.html to your browser.
We recommend you con gure 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 di erent 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:
runs the web server in background and the webpack in foreground within a single window.
On Windows you can start the web server in background and webpack in foreground with the two Windows commmands:
You can stop the background webserver with the command:
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 le 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
(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 con g le webpack.config.js (http://localhost:3000/webpack.config.js) directs that this bundle be created from the ReactJS le 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 le 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 les components/example/{Example.jsx,Example.css} .
You should look through the les invoked in the getting-started.html view ( 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 le 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 le 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:
1. Update the model data for the Example component to use your name rather than "Unknown name". You should nd where "Unknown name" is and replace it.
2. Replace the contents of the div region with the class motto-update in 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 in Example.css .
3. 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 retrieved 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 eld which accepts a substring. The view will display in alphabetical order a list of all states whose names contain the given substring (ignoring di erences 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 lter 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:
See states.js for a description of the format of the states data.
To help you get started and guide you to the le naming conventions we want you to use we provided a le 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 le in your browser via the URL http://localhost:3000/p2.html (http://localhost:3000/p2.html).
The les 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 ). Note that you should not replace the section from part 1 (your name and motto). That section should be separate from your 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 les you will need to implement are:
components/header/Header.jsx - The ReactJS Component of your header component. This is de ned a class Header of type React.Component (https://reactjs.org/docs/react-component.html). components/header/Header.css - Any CSS styles your component needs. You must include some styling for your header here.
Note: gettingStarted.jax should have a personalized header from Problem 3 at he top of the page and the section with the motto from Problem 1.2 right below it. All other page views ( p2.html , p4.html and p5.html ) should 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 le 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 les above as well as modify the webpack con guration le webpack.config.js to build a le compiled/p4.bundle.js that you can uses in p4.html le. Note that if you are using Webpack with --watch (i.e. npm run build:w), you will need to
restart it after changing codewebpack.con g.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 de ciency by storing the view information into the URL. React Router (https://reacttraining.com/react-router/) provides this functionality for ReactJS. For this problem make a copy of your p4.html solution into a le named p5.html and copy your p4.jsx into a le named
p5.jsx . Convert the code to use React Router (https://reacttraining.com/react-router/) to switch between the two component views. You should have a
styled toolbar-like control (simple plain text links are not su cient) that will allow the user to switch between the example and states component views.
Since this is the rst extensions from the core ReactJS we import, we provide you with step-by-step instructions.
1. The project's package.json speci es react-router so the npm install command already fetched it for us. We do need to explicitly import it into our p5.jsx le. Add the following import line:
The line uses the JavaScript import (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/importinport) statement to bring in the ReactJS components from React Router: HashRouter (https://github.com/ReactTraining/react-router/blob/master/packages/reactrouter-dom/docs/api/HashRouter.md), Route (https://github.com/ReactTraining/react-router/blob/master/packages/reactrouter/docs/api/Route.md), and Link (https://github.com/ReactTraining/react-router/blob/master/packages/react-router-dom/docs/api/Link.md). The HashRouter module of React Router uses the fragment portion of the URL for storing infomation. So we can make p5.html#/states mark showing the States view while p5.html#/example speci es the Example component view.
2. 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
(https://github.com/ReactTraining/react-router/blob/master/packages/react-router/docs/api/Route.md) component that implements this condition rendering when placed inside a HashRouter element like:
which would render the States component if the URL had #/states and the Example component if the URL had #/example .
3. Although we could use hyperlinks (i.e. <a tags) to switch views react router recommends using the Link component to generated the hyperlinks.
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. ESLint should raise no errors.
Deliverables
After implementing part 5, make sure parts 1 through 4 still work!
Use the standard class submission mechanism (submit.html) to submit the entire application (everything in the project4 directory).