I've built a Netflix clone using React and TMDB API

diogo405

Diogo Goncalves

Posted on October 2, 2020

I've built a Netflix clone using React and TMDB API

Hey! I finally finished this Netflix clone (took me more time than I expected 😅) and uploaded to Netlify. You can check this out here.

Alt Text



My idea was to make everything static (movies, series, tv shows, ...) but then I found this really cool TMDB API which you can pull most popular movies, top rated shows, what's trending, collections, lists and muuuch more. Really worth checking 👀

After that, I wanted to use something to separate the UI state from the API data. I ended up using React-Query to fetch the Movie API which I found really nice. You need to pass a key and a function to grab the data you want. It returns the API response, a flag indicating if it's loading and another one if there was an error or not.

const {data: heroData, isLoading: heroIsLoading, error: heroError} = useQuery('hero', async () => {
    const res = await fetch(`${process.env.REACT_APP_TMDB_BASE_URL}/movie/558?api_key=${process.env.REACT_APP_TMDB_KEY}`)
    const data = await res.json()
    return data
})
Enter fullscreen mode Exit fullscreen mode

Components

The hardest part was to build the home page. I had a look at Netflix website and thought what parts would be my React components.

Alt Text

Once the home page was built, I kind of developed the TV Shows and Movies page re-using what I had done before. The layout of each page is different but they still use the same components.

State Management

At the beginning I thought I would use Context API but it needs to pass from parent to siblings (could've put as the root element but...). I tried to understand Redux and found a bit overwhelming 😬 My choice was Recoil, I'm using its basic hooks (useRecoilState, useSetRecoilState) and atoms. Didn't dive into selectors and others features.

Other Stuff

Lastly, for routing I'm using React Router and Code-Splitting the page components in App.js.

const HomePage = React.lazy(() => import('./pages/HomePage.js'));
const VideoPage = React.lazy(() => import('./pages/VideoPage.js'));
const ShowsPage = React.lazy(() => import('./pages/ShowsPage.js'));
const MoviesPage = React.lazy(() => import('./pages/MoviesPage.js'));
...
<RecoilRoot>
    <Router>
        <FeedbackPopup/>
        <Suspense fallback={<div></div>}>
            <Switch>
                <Route exact path="/">
                    <Topbar/>
                    <HomePage/>
                </Route>
                <Route path="/playing/:type/:id">
                    <VideoPage/>
                </Route>
                <Route path="/tv-shows">
                    <Topbar/>
                    <ShowsPage/>
                </Route>
                <Route path="/movies">
                    <Topbar/>
                    <MoviesPage/>
                </Route>
            </Switch>
        </Suspense>
    </Router>
</RecoilRoot>
Enter fullscreen mode Exit fullscreen mode

You can found the code at my Github. Any feedback is very welcome 👍🏽

Happy coding 😃

💖 💪 🙅 🚩
diogo405
Diogo Goncalves

Posted on October 2, 2020

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related