Assignments > Lab 8. React
Due on Fri, 05/21 @ 11:59PM. 10 Points.
Required Readings
Before beginning this week’s lab, please complete the React Step-by-Step Guide. It will take you and hour, but if you’re new to React it’s an hour well spent. It will be impossible for you to work effectively in React without understanding the core conventions and workflow, including:
Instructions
In this week’s lab, you will be re-implementing a subset of your Doctor Who UI using React. The following 5 tasks are required in order for you to get full credit for the lab:
- Create a component hierarchy
- Create stubs for each component
- Implement the doctors list
- Implement the doctor “detail view”
- Implement the companions list
We’ll just be grading you on #3, #4, and #5.
Update: Video Walkthroughs
Here are some video walkthroughs if you want to see me solve this challenge. They’re by no means professional quality, but hopefully they are of some value to you all!
Required Tasks
Download lab08.zip
, unzip it, and open the folder in VSCode.
From your command line, navigate to the lab08
directory and install the required packages with npm install
and run the server locally using npm start
.
Note: Although we are using Node to build and run our React app, we will ultimately be compiling our React app to HTML, CSS, and JavaScript so that the browser can download these files from our website and run them client-side. It’s confusing, but the final output of our React App is client-side code that our browser will run.
Step 1: Component Hierarchy
As described in the Thinking in React piece, it is important to be able to look at a wireframe / mockup and consider what might constitute a component (keeping in mind that components can have child components).
Given (a) the starter App.js
file we have given you and (b) what you already know about the “Doctor Who” app you made in Homework 3, think about how you might break up this web app into different components, where each one does a small job within the larger application:
import React from 'react';
class App extends React.Component {
render () {
return (
<div className="container">
<header className="header">
<h1>Doctor Who Editor</h1>
</header>
<aside className="aside">
List of doctors goes here.
</aside>
<main className="main">
<div className="doctor">
<h2>Current Doctor</h2>
<p>Current doctor goes here</p>
</div>
<section className="companions">
<h2>Companions</h2>
<p>Companions go here</p>
</section>
</main>
</div>
);
}
}
export default App;
One potential strategy (though there could certainly be others) might involve splitting up your functionality into 4 components, where each component has 1 job:
Header component | Responsible for displaying the header (and perhaps a menu down the line). |
DoctorList component | Responsible for displaying a list of doctors (that a user can click on to get more detail). |
DoctorDetail component | Responsible for displaying the selected doctor. |
CompanionList component | Responsible for displaying the companions that travel with the selected doctor. |
Think about what your render() function might look like for each component, and which of your components might issue fetch requests.
Step 2: Create stubs for each component
Once you’ve decided on your components, create a JavaScript file for each component in your src
directory. In each JavaScript file, create a react component, and a simple render function that renders only the JSX elements associated with it. So, for instance, the DoctorList would render the aside
element (and eventually the list of doctors):
import React from 'react';
class DoctorList extends React.Component {
render () {
return (
<aside className="aside">
List of doctors goes here.
</aside>
);
}
}
export default DoctorList;
When you’re done creating all of your components, refactor your App.js
so that the render function is using your React components (don’t forget to import them all). Note that in the sample code shown below, the Header
component is accepting a custom property called “title.” Please review components and props if you have any questions about how that works.
render () {
return (
<div className="container">
<Header title="Doctor Who Editor" />
<DoctorList />
<main className="main">
<DoctorDetail />
<CompanionList />
</main>
</div>
);
}
If you get stuck, please take a look at hints/hint-1
.
Step 3. Implement the “Doctor List” Functionality
Next, modify the logic of your DoctorList
component to display all of the doctors in the list. Recall that in the React model, your fetch logic and your rendering logic are decoupled. In other words, you’ll probably want to:
- Fetch the doctors from a working “Doctor Who” endpoint (we recommend running your HW3 node instance and accessing this endpoint: http://localhost:8081/doctors.
- Save the doctors in your state object.
- Render the doctors (recall that each time you issue a call to the built-in
this.setState()
method, React automatically re-renders your component – like magic).
Step 4. Implement the “Doctor Detail” Functionality
When the user clicks on one of the doctors, display a panel showing the doctor’s name, picture, and seasons. To do this, you’re going to have to figure out how to communicate between your components. When you click on a doctor in your DoctorList
component, how can notify your DoctorDetail
component to render? To learn how this might be done, re-read the lifting up state page, which provides guidance. The strategy discussed involves:
- Creating an event handler in the component that is a parent of both the
DoctorDetail
and theDoctorList
component (theApp
component) - Making the event handler available to the
DoctorList
component by passing it in as a property. - Assigning the event handler to the click event of each doctor in the list.
When a doctor in the list is clicked, the event handler is fired. And, because the event handler belongs to the App
component, it will be able to pass data (the selected doctor) to the DoctorDetail
component.
Step 5. Implement the “Companions List” Functionality
When the user clicks on one of the doctors, also display a panel showing all of the companions that traveled with that selected doctor. See if you can figure out how to do this.
Recommended Tasks
While not required, we strongly encourage you to also try implementing the “create,” “update,” and “delete” doctor functionality. By doing this part of the lab, you will be able to experience some of the challenges of coordinating state across your components (which is not as easy to appreciate when building smaller interfaces). It will also provide the motivation behind why people who build complex SPAs (single page applications) use tools like Redux to manage state across an application.
Recommended additional tasks to complete:
- Implement the create doctor
- Implement the edit doctor
- Implement the delete doctor
When implementing the create / edit / delete functionality, please draw heavily on the HTML template literals you made in Homework 3. Please also refer back to the forms tutorial, which provides a suggestion around how to use the component’s state to manage form updates.
What to Turn In
When you’re done, zip your src
and public
directories and submit your zip file to Canvas.