Create a Movie App With React and TMDB API
Published: 2023-09-24 13:28:28

In this tutorial, we will walk you through the process of creating a movie app using React.js and the TMDB API, ensuring a beginner-friendly and well-explained approach.

**Table Of Contents:**
1. [What is TMDB API](#1-what-is-tmdb-api)
2. [Install React and Set up React App](#2-install-react-and-set-up-react-app)
3. [Generate TMDB API](#3-generate-tmdb-api)
4. [Create .env file](#4-create-env-file)
5. [Create context folder and stateContext.jsx file](#5-create-context-folder-and-statecontextjsx-file)
6.0Create Navbar.jsx and paste this code

### 1. What is TMDB API
The TMDB API provides a comprehensive list of available methods for movies, TV shows, actors, and images. For more information about the API, [click here](https://developer.themoviedb.org/reference/intro/getting-started).

### 2. Install React and Set up React App
   a. Create a React app using Vite:
   ```bash
   npx create-vite your_app_name --template react
   ```
   Once created, run:
   ```bash
   npm install react-icons --save
   npm i react-router-dom
   ```
   Access the final code on [GitHub - KareemSulaimon/movieApp](https://github.com/KareemSulaimon/movieApp).

### 3. Generate TMDB API
1. Follow this [link](https://developer.themoviedb.org/reference/intro/getting-started) and sign up for an account.
2. Choose JavaScript as your preferred language and click "Get API Key."
3. Continue, input your data and URL path (GitHub or personal website link).
4. Check your notifications for your API Key.

### 4. Create .env file
1. Outside the src folder, in your root directory, create
   ```bash
   touch .env
   ```
   Inside the .env file:
   ```plaintext
   VITE_REACT_APP_API_URL=https://api.themoviedb.org/3/
   VITE_REACT_APP_API_KEY=put your generated API key here
   ```
   Note: We are starting the naming with VITE_REACT because we created it with a React app. It would have been REACT_ .... if we created it for React only.

### 5. Create context folder and stateContext.jsx file
```bash
touch context/stateContext.jsx
```
Context provides a way to pass data through the component tree without having to pass props down manually at every level. Read more here: [React Context](https://react.dev/reference/react/createContext).

In your 'stateContext.jsx' file, copy and paste this code:

```jsx
import React, { createContext, useContext } from 'react';

const Context = createContext();

const StateContext = ({ children }) => {
  const baseImageUrl = 'https://image.tmdb.org/t/p/original';
  const apiUrl = import.meta.env.VITE_REACT_APP_API_URL;
  const apiKey = import.meta.env.VITE_REACT_APP_API_KEY;

  return (
    <Context.Provider
      value={{
        baseImageUrl,
        apiUrl,
        apiKey
      }}
    >
      {children}
    </Context.Provider>
  );
};

export const useStateContext = () => useContext(Context);
```
**6.Create Navbar.jsx and paste this code**

```
import React from 'react';
import { BiSearch } from 'react-icons/bi';
import menu from '../assets/menu.png';
import logo from '../assets/logo.png';
import { useStateContext } from '../context/StateContext';
import { Link, Form } from 'react-router-dom';

function Navbar() {
  const { handleFormSubmit , query, handleInputChange } = useStateContext();
 
  return (
    <div className="flex flex-col sm:flex-row w-full justify-center sm:justify-around gap-4 items-center z-20 absolute top-10" data-testid="navbar">
          <Link to={"/"} className='flex items-center' data-testid="logo-link">
              <img src={logo} alt="logo icon" data-testid="logo-img" />
          </Link>
          <Form onSubmit={handleFormSubmit } className="flex w-3/5 sm:w-2/5 h-4 items-center border-white border-2 p-4 rounded-lg shadow-md" data-testid="search-bar">
            <input
              type="text"
              placeholder="What do you want to watch?"
              value={query}
              onChange={handleInputChange}
              className="w-full placeholder-white bg-transparent border-none outline-0 text-sm text-white sm:text-lg"
              data-testid="search-input"
            />
            <BiSearch className="text-white font-bold" data-testid="search-icon" />
    </Form>
    <div className="flex items-center" data-testid="menu-icon">
      <img src={menu} alt="menu icon" />
    </div>
  </div>
  );
}

export default Navbar;
```
Then, in `Navbar.jsx`:
1. The images are located in the assets folder.
2. The `Form` and the `Link` components are imported from `react-router-dom`, which was previously installed. When the `Form` is submitted, the `onSubmit` method calls `handleFormSubmit`, a function that will be defined later in `stateContext.jsx`. Likewise, the `onChange` method calls `handleInputChange` whenever a change is made to the query value.