LAB/Exercise to practice React concepts (React Router, props, state, useEffect, API requests...)
We're going to create a React application that interacts with an external API. It will have functionality to get information about apartments & create new apartments.
Sitemap/Wireframes:
- We will follow these wireframes: https://whimsical.com/react-ironbnb-MVw1gkTJrekF2QTaEKCMJU
-
We will interact with Ironbnb API.
-
BaseURL: https://ironbnb-m3.herokuapp.com
-
Supported endpoints:
HTTP verb | URL | Request body | Action |
---|---|---|---|
GET |
/apartments |
- - - | Returns an array with all the apartment documents. |
GET |
/apartments/:id |
- - - | Returns an apartment document by its id. |
POST |
/apartments |
{ img: String, title: String, pricePerDay: Number } |
Creates a new apartment document. |
- As you can see, it follows REST.
- Responses are in JSON.
- Fork + clone
- Install dependencies
- Run the app (hint: check package.json)
Create the following components (for now, just display an <h1>
in each component):
- NavBar
- HomePage
- ApartmentsList
- ApartmentDetails
- CreateApartment
Setup routing. You will need this behaviour:
- The
<NavBar />
component should be displayed in all pages - If user visits
/
, display the<HomePage />
component - If user visits
/apartments
, display<ApartmentsList />
- If user visits
/apartments/42
, display<ApartmentDetails />
(note, that42
must be dynamic -- use URL params) - If user visits
/apartments/create
, display<CreateApartment />
(note: in the code, you may need this route earlie... otherwise "create" will be treated as an apartment id)
Implement the NavBar with links, so that the user can navigate (hint <NavLink>
).
IMPORTANT:
- For this iteration, do not implement the details of each component, just the general structure (make sure the user can navigate through the app).
- For the components hierarchy, keep all components as direct children of App.
Implement <ApartmentsList />
, so that it makes a request to the API and displays a list with all apartments.
Hint: you will need to use useEffect()
.
For now, don't worry about the button "more details" (we will implement this functionality later).
Implement the logic for <CreateApartment />
.
- You will need a form (controlled component).
- When user submits, we need to send a POST request to the API.
- Once we get the response from the API, we can redirect the user to the list of apartments
- do some research on how to redirect with react-router (hint: the library provides a custom hook
useNavigate()
)
- do some research on how to redirect with react-router (hint: the library provides a custom hook
Implement the logic for <ApartmentDetails />
.
This component should make a call to the API and display the details of an apartment, based on its id.
Store API baseUrl in .env (since we're using Create React App, make sure your environment variable starts with the prefix REACT_APP_
)
- Submit Pull Request (same process as usual).
- For this lab, no need to submit in students portal.
- Single API call to get the info (instead of calling the API in
<ApartmentsList>
and<ApartmentDetails>
)- Make one single call to the API in
<App>
- Pass the info as props to
<ApartmentsList>
and<ApartmentDetails>
- Make one single call to the API in
- Conditional rendering: if an apartment has no image, display a default image
- Conditional rendering: if data from the API is not ready, display a message "loading"
- Display spinner/loader while data is loading
- Option 1: there's many websites where you can find CSS for "spinners", for example here. You can copy the CSS and then render a div with that specific className.
- Option 2: render a component from a component library. For example, if you're using Ant Design, you can use this component
- CSS: Apply different ways to style React components (inline css, plain css with one file per component, scss...).
- CSS: use a component library (ex. React Bootstrap, Semantic UI, Ant Design, Chakra, Material UI...)
- (advanced) create a service (a function or class in charge of all requests to the api)
- (advanced) Convert all function components to class components (note: the syntax to use props, state and api requests is a bit different in class components; do some research)