This is an entertainemnt app that displays movies and TV shows. Users can search for a title and see a collection of movies matching that title. Alternatively, there is a collection of different genres, including a trending section, on the TV and Movie pages.
Users can click on any title to see more information including a rating, runtime and plot overview.
Any title can also be added to a users bookmark collection. Bookmarks are saved to localStorage
.
I want to learn, implement and understand the advantages of React Router and CSS Grid while also gaining more experience building React applications.
The various pages required for this project make it a great opportunity to dive into React Router and the gallery style layout of the movies looks like a prime candidate for a Grid implementation. This project will also help me practice using stateful variables, Hooks and reusable components to build an interactive UI.
- Semantic HTML5 markup
- CSS custom properties
- Flexbox
- CSS Grid
- TMDB API
- React - JS library
- React Router - React routing library
This project presented many challenges and even more learning opportunities. Below are some notes on key lesson I learned that hopefully save someone the struggle of learning them the hard way.
Problem
- I was attempting to access a
release_date
property that didn't exist on some media objects returned by TMDB. As a result, searching for certain movies would cause a black screen along with Error: Cannot read property 'slice' of undefined
Solution
- Use short circuit evaluation to only render a property if it exists. In my case:
{ movie.release_date &&
<p>
{movie.release_date.slice(0,4)}
</p>
}
- The right side of the
&&
operator will only render if the left side is truthy. This prevents acessing properties that don't exist
Alternatives
- According to this article, you could use a ternary operator to accomplish the same thing
{ movie.release_date
? <p>{movie.release_date.slice(0,4)}</p>
: null
}
Problem
- Clicking on a movie bookmark button was not filling in the bookmark icon. The movie was being added to a stateful
favorites
array but no re-render occurred - This article helped me realize the problem. I was attempting to set the state of
favorites
using the same object reference. This prevented React from perceiving any changes in the state and thus didn't cause a re-render
//no re-render
const [favorites, setFavorites] = useState([])
favorites.push(movie)
setFavorites(favorites)
Solution
- In order for React to detect a change, set state using a new array
//re-render
setFavorites([
...favorites,
movie
])
Problem
- In order to determine whether to add or remove a movie from
favorites
, when a movie bookmark was clicked I used the following code to check if the movie was already infavorites
const inFavs = favorites.some(fav => fav === movie)
- The code worked as I intended... as long as the user didn't refresh the page. After refreshing if a user clicked on
a bookmarked movie,
inFavs
evaluated tofalse
and the movie was added tofavorites
again.
Solution
- After some Googling I found two articles on values and references and comparing objects
- The code above only evaluates to
true
if the two values reference the same object instance. This was was the case before refreshing, since all movie object instances came from TMDB. After refreshing,favorites
is retrieved fromlocalStorage
and any movie objects infavorites
now have a different reference than those fetched from TMDB. As a result, usinginFavs
to compare two value identical movies, one from TMDB and the other fromlocalStorage
, evaluates tofalse
- To avoid this reference comparison I manually compared the
id
property of both movies
const inFavs = favorites.some(fav => fav.id === movie.id)
Not included in this list are the challenges faced and lessons learned from using React Router, implementing CSS Grid, using React Hooks, avoiding prop drilling, using media queries and all the other bumps along the way.
Together these challenges greatly improved and reinforced my understanding of JavaScript and React.
- Add a user login
- Include TV shows in the user search
- Add a trailer to the movie info page
-
Frontend Mentor - The awesome site that provided the design files and inspiration for this project
-
Understanding React Re-Renders - Super useful article that helped me better understand when/why React re-renders
-
Comparing objects - Another useful post to better understand the not so intuitive aspects of object comparisons
-
Great guide for React Router. I didn't use anywhere near all the topics covered and will definitely be coming back to reference it in future projects.
I want to give another huge thanks to Frontend Mentor for the resources and challenges they provide.