Building a Movie Search App in React for Beginners
React is one of the most popular front-end libraries for building web applications. In this article, we'll walk you through how to build a movie search app in React from scratch. This tutorial is designed for beginners who want to learn the basics of React and API consumption.
Prerequisites
To get started with this tutorial, you'll need:
- Basic knowledge of HTML, CSS, and JavaScript.
- A text editor or an integrated development environment (IDE) like Visual Studio Code.
- Node.js installed on your computer. You can download the latest version from the official website.
- A free OMDB API key (you can get one here)
Project Setup
Let's start by creating a new React project using Create React App. Open your terminal and run the following command:
npx create-react-app movie-search-app
This command will create a new React project called movie-search-app
and install all the necessary dependencies.
Folder Structure
Next, let's create a folder structure for our project. Create a new folder called src
in the root directory of your project. Inside the src
folder, create three new folders called components
, pages
, and utils
.
- The
components
folder will contain all the reusable React components that we'll use throughout our app. - The
pages
folder will contain the main screens of our app, such as the home page and search results page. - The
utils
folder will contain any utility functions or reusable logic that we'll use throughout our app.
Your project structure should look like this:
movie-search-app/
├── node_modules/
├── public/
│ ├── favicon.ico
│ ├── index.html
│ └── manifest.json
├── src/
│ ├── components/
│ ├── pages/
│ └── utils/
│ ├── App.css
│ ├── App.js
│ ├── App.test.js
│ ├── index.css
│ ├── index.js
│ └── logo.svg
├── .gitignore
├── package.json
├── README.md
└── yarn.lock
API Key
Now that we have set up our project, let's get an API key from the OMDB API for movie data. To get an API key, go to the OMDB API website and follow the instructions to get a free API key.
Home Page
Let's start building the home page of our movie search app. Inside the pages
folder, create a new file called Home.js
.
import React from 'react';
function Home() {
return (
<div>
<h1>Movie Search App</h1>
<p>Search for your favorite movies and TV shows!</p>
</div>
);
}
export default Home;
This is a simple React functional component that will render the home page of our app. We're displaying a heading and a short description to welcome users to our app.
Now let's create a new file called App.js
in the root of src
. We'll use this file to import and render our Home
component.
import React from 'react';
import Home from './pages/Home';
function App() {
return (
<div>
<Home />
</div>
);
}
export default App;
This is the main component of our app. We're importing and rendering the Home
component inside our App
component.
Fetching Movie Data
Now let's create a new file called MovieList.js
inside the components
folder. This component will display a list of movies based on the user's search query.
import React, { useState, useEffect } from 'react';
function MovieList({ searchQuery }) {
const [movies, setMovies] = useState([]);
useEffect(() => {
fetch(`http://www.omdbapi.com/?apikey=YOUR_API_KEY&s=${searchQuery}`)
.then(response => response.json())
.then(data => setMovies(data.Search));
}, [searchQuery]);
return (
<div>
{movies.map(movie => (
<div key={movie.imdbID}>
<h2>{movie.Title}</h2>
<p>{movie.Year}</p>
<img src={movie.Poster} alt={`${movie.Title} Poster`} />
</div>
))}
</div>
);
}
export default MovieList;
The MovieList
component takes a searchQuery
prop, which is the user's search query. We're using the useState
hook to keep track of the movies returned by the API and the useEffect
hook to fetch the movie data when the searchQuery
prop changes.
We're using the fetch
API to make a request to the OMDB API endpoint and passing in the searchQuery
as a URL parameter. Once we receive the data, we're updating the state using the setMovies
function.
Finally, we're rendering a list of movies by iterating over the movies
state using the map
function and displaying each movie's title, year, and poster.
Search Form
Next, let's create a search form component that will allow users to search for movies. Create a new file called SearchForm.js
inside the components
folder.
import React, { useState } from 'react';
function SearchForm({ handleSearch }) {
const [searchValue, setSearchValue] = useState('');
function handleSubmit(event) {
event.preventDefault();
handleSearch(searchValue);
}
return (
<form onSubmit={handleSubmit}>
<input
type="text"
placeholder="Search for a movie or TV show..."
value={searchValue}
onChange={(event) => setSearchValue(event.target.value)}
/>
<button type="submit">Search</button>
</form>
);
}
export default SearchForm;
The SearchForm
component takes a handleSearch
prop, which is a function that will be called when the user submits the form. We're using the useState
hook to keep track of the search query that the user enters in the input field.
When the user submits the form, we're handling the form submission by calling the handleSubmit
function. We're preventing the default form submission behavior using the preventDefault
method and calling the handleSearch
function, passing in the searchValue
state as an argument.
Finally, we're rendering a simple search form with an input field, a submit button, and some placeholder text.
Search Results Page
Now that we have the components to fetch movie data and search for movies, let's create a search results page that will display the search results. Create a new file called SearchResults.js
inside the pages
folder.
import React, { useState } from 'react';
import SearchForm from '../components/SearchForm';
import MovieList from '../components/MovieList';
function SearchResults() {
const [searchQuery, setSearchQuery] = useState('');
function handleSearch(searchValue) {
setSearchQuery(searchValue);
}
return (
<div>
<SearchForm handleSearch={handleSearch} />
<MovieList searchQuery={searchQuery} />
</div>
);
}
export default SearchResults;
The SearchResults
component is rendering the SearchForm
and MovieList
components that we created earlier. We're using the useState
hook to keep track of the search query entered by the user, and we're passing the searchQuery
state as a prop to the MovieList
component.
We're also passing a handleSearch
function as a prop to the SearchForm
component, which will be called when the user submits the form.
Routing
Now that we have the home page and search results page components, let's add routing to our app. We'll use the react-router-dom
package to manage routing in our app.
First, let's install the react-router-dom
package by running the following command in your terminal:
npm install react-router-dom
Next, let's import and use the BrowserRouter
and Route
components from the react-router-dom
package inside our App
component.
import React from 'react';
import { BrowserRouter, Route } from 'react-router-dom';
import Home from './pages/Home';
import SearchResults from './pages/SearchResults';
function App() {
return (
<BrowserRouter>
<div>
<Route exact path="/" component={Home} />
<Route path="/search" component={SearchResults} />
</div>
</BrowserRouter>
);
}
export default App;
We're wrapping our entire app in the BrowserRouter
component and using the Route
component to define our app's routing. We're defining two routes: one for the home page ("/"
) and one for the search results page ("/search"
").
Styling
Finally, let's add some styling to our app to make it look more visually appealing. Create a new file called App.css
in the src
folder and add the following styles:
body {
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
background-color: #262626;
color: #fff;
margin: 0;
}
.container {
max-width: 900px;
margin: 0 auto;
padding: 20px;
}
h1 {
font-size: 48px;
font-weight: normal;
margin-bottom: 20px;
}
p {
font-size: 24px;
margin-bottom: 20px;
}
form {
display: flex;
margin-bottom: 20px;
}
input[type="text"] {
flex: 1;
padding: 10px;
font-size: 20px;
border: none;
border-radius: 5px 0 0 5px;
}
button[type="submit"] {
padding: 10px 20px;
font-size: 20px;
border: none;
border-radius: 0 5px 5px 0;
background-color: #ff2e63;
color: #fff;
cursor: pointer;
transition: background-color 0.2s ease-in-out;
}
button[type="submit"]:hover {
background-color: #e6005c;
}
img {
max-width: 100%;
height: auto;
margin-bottom: 20px;
}
We're adding styles to our app using CSS. We're setting the font family, background color, and text color for the entire body of our app. We're also adding styles for specific components like the header, search form, and movie list.
Conclusion
In this article, we covered the basics of building a movie search app in React. We started by creating a new React project using Create React App, added components to fetch movie data and search for movies, and implemented routing to navigate between the home page and search results page.
We also added some basic styles to make our app look more visually appealing. With these skills, you're ready to take on more complex React projects and explore different APIs to build dynamic web applications.