HW 5 - Advanced React
While we've worked on basic React sites that are static, real world applications interact with servers and databases over the internet. In ths homework, we'll be tieing together the frontend and the backend aspects of this course.
Learning Objectives
- Further practice with React syntax
- Introduce Axios
- Use HTTP methods to access RESTful services
- Create your first custom hook
- Use fetched data to create a dynamic application
Setup
The starter code for this homework is in Classroom: https://classroom.github.com/a/tj0DPN1c
Take a look around the codebase and try to understand how it's put together.
Task 1 - Start the Backend
Before we start building anything, we have to set up our server first. For this instance we will be using Express. The server will already be pre-built for you, feel free to look to examine the code and don't stress if you don't understand it. You'll only be worrying about the React side of things:
- cd into the directory:
cd homework5-starter/node-server
- Install dependencies:
npm i
- Run the server:
npm start
You should see output that looks something like this:
❯ npm start
> node-server@1.0.0 start
> node index.js
Block Server listening at http://localhost:3002
Task 2 - Start the Frontend
Congrats! The backend server is now running at localhost:3002
. Now for a
production application, we'd also often be running a database such as MongoDB,
but if you examine the index.js
file, you'll see that we've hard-coded the data you're
fetching.
For this task, we'll introduce fetching data to a server from our frontend.
As you know, we can use HTTP requests to send and receive data over the
internet. In fact, opening a website like google.com
is an HTTP GET request!
Servers are similar, they have various routes that contain HTTP endpoints that
you can trigger.
By default, browsers have the fetch
API built in to give your frontend
javascript the ability to fetch resources across a network. You can read more
about Fetch here.
While fetch is incredibly powerful, it's also a bit more barebones and complex, so we'll be using a wrapper around Fetch called Axios.
First, lets install Axios! Open a new terminal and navigate to the react-app
folder and run the below command:
npm install axios
And now lets start the app:
npm start
Make sure that your express server and React app are on different ports.
Task 3 - Write an API request
Now that your frontend and backend are working, lets write a HTTP request.
First, lets see how Axios works in an example:
function Example() {
const [data, setData] = useState();
const getPostsData = () => {
axios
.get('https://jsonplaceholder.typicode.com/posts') //THIS IS YOUR URL OF YOUR API
.then((data) => setData(data.data)) //PROMISE API, ONCE YOU GET THE DATA WHAT DO YOU WANT TO DO WITH IT?
.catch((error) => console.log(error)); //ERROR CATCHING IN CASE WE RECEIVE AN ERROR RECIEVING THE DATA
};
useEffect(() => {
getPostsData();
}, []);
return <p>{data ? JSON.stringify(data[0]) : 'loading'}</p>;
}
In this example, our function getPostsData
calls the API using a GET
request. This function is called in a useEffect
hook on first render. We then
wait for the promise resolve using a .then
, and once resolved, set our state
variable data
to the returned data. We also catch the error if the promise
returns an error.
Confused by the hooks? As a reminder,
- useEffect hooks run the function passed into the first parameter if any
variable in the array passed in as the second parameter changes.
- In this example, there are no variables passed in the second arg, so this will run when the component first mounts (is rendered)
- useState hold pieces of state, and a
setState
call will trigger a component re-render
Cool, now that you know any example of how we might fetch data, how might you use this data to render out posts in our application?
Action Items
In Feed.js
, fill in the blanks to make an API request. Fetch data from our server (http://localhost:3002/posts
) and render out each
array item using the Post
component inside of the Feed
component. (You can leave line 50 as a blank for now!)
Tips:
- Make sure your server URL is passed in the get logic correctly
- Where would the fetch logic be placed?
Task 4 - Creating a new post
Now that we can view posts from our server, you'll notice that there's a form at the bottom to create a new post. We've already built the logic to get the form data, you'll be using a post request to add this data to our server.
Axios post requests are very simple, as an example:
axios
.post(url, data) // `url` is the url to post to, `data` is the data to send in the body of the HTTP request
.then((response) => console.log(response))
.catch((error) => console.log(error));
Action Item
- In
Feed.js
, fill in the blank in line 50. Pass in a function to aNewPost
component through a prop. - In
NewPost.js
, fill in the blanks for creating a new post by making aPOST
request. - Fill in the blank in line 4 to accept the passed in property and use that property after the post request.
Tips
- To create a new post, you'll have to
POST
/post
Task 5 - Working with Comments
At this point, you should be able to view and create new posts. Now, we'll do the same for comments.
There's a comments
field on the server data, and if you POST
/post/:id/comment
, you'll be able to add a new comment.
Action Item
- Fill in the blanks in
Comments.js
to handle and submit the new comment. - Fill in the blanks in
Post.js
to pass in correct props toComments
component.
Tips
- In
.then
body, change the states to reflect the new comment and clear thenewComment
state.
Submission
After you finish, push these changes into your Classroom repository.
- Turn your code into Gradescope for the assignment Homework 5.
- This assignment has a checkoff component. To get credit, you must get checked off. We will specifically carve out time during lecture just for check offs.
Demo of Solution
When finished, your website should be able to run like the follow:
Note the UI doesn't have to be the same.
Contributors
- Caelin Sutch
- Rebecca Won
- Ethan Pang