This article covers how to make a fully responsive and sleek Movie App with React. React is a JavaScript framework provided by Facebook and is used to build fully-featured web applications.
We will be following the below steps for creating our application:
Step 1: Creating the project: We will start by creating a new react project using the create-react-app tool. You can use the following command for creating one with the desired name. Please ensure that Node and npm are installed on the system.
npx create-react-app movie-app
Project Structure: We will then delete all the files that are not necessary. The file structure after deleting the files is given below:
Step 2: Open the “src” folder and select the App.js file and add the following code to it.
App.js
import React, { useState } from "react"; import axios from "axios"; import Search from "./components/Search"; import Results from "./components/Results"; import Detail from "./components/Detail"; import "./App.css"; function App() { const [state, setState] = useState({ s: "sherlock", results: [], selected: {}, }); const searchInput = (e) => { let s = e.target.value; setState((prevState) => { return { ...prevState, s: s }; }); }; const search = (e) => { if (e.key === "Enter") { axios(apiurl + "&s=" + state.s).then(({ data }) => { let results = data.Search; console.log(results); setState((prevState) => { return { ...prevState, results: results }; }); }); } }; const openDetail = (id) => { axios(apiurl + "&i=" + id).then(({ data }) => { let result = data; setState((prevState) => { return { ...prevState, selected: result }; }); }); }; const closeDetail = () => { setState((prevState) => { return { ...prevState, selected: {} }; }); }; return ( <div className="App"> <header className="App-header"> <h1>Movie Mania</h1> </header> <main> <Search searchInput={searchInput} search={search} /> <Results results={state.results} openDetail={openDetail} /> {typeof state.selected.Title != "undefined" ? ( <Detail selected={state.selected} closeDetail={closeDetail} /> ) : ( false )} </main> </div> ); } export default App; |
App.css
* { margin: 0; padding: 0; box-sizing: border-box; } body { font-family: "montserrat", sans-serif; background: linear-gradient(to right, #000428, #004e92); } header { width: 100%; padding-top: 2rem; padding-bottom: 1rem; } header h1 { color: #ffffff; font-size: 4rem; font-weight: 700; text-align: center; } main { width: 100%; max-width: 90%; margin: 0 auto; } .results { display: flex; flex-wrap: wrap; justify-content: center; align-items: center; /* margin: 0 -15px; */} .results .result { width: 20%; min-width: 250px; background: #000000; max-height: 500px; /* padding: 15px; */ margin: 20px 25px; display: flex; flex-direction: column; cursor: pointer; } .results .not-found { display: flex; flex-direction: column; justify-content: center; align-items: center; text-align: center; margin: 2rem 0.5rem; } .results .not-found h2 { color: #ffffff; } .results .result img { /* display: block; */ width: 100%; padding: 10px 2px; margin: 0 auto; height: 350px; width: 230px; } .results .result h3 { color: #fff; font-size: 20px; font-weight: 600; width: 100%; text-align: center; padding: 1rem; background: #272829; flex: 1 100%; transition: 0.4s ease-out; } .result:hover { box-shadow: 0 0 8px 3px #eaf0f7; /* background: #dfd8d8; */} .results .result h3:hover { background: #fff; color: #223343; box-shadow: 0 0 8px 3px #4484c4; } .detail { margin: 3rem 5rem; overflow-y: scroll; } .detail .content .rating { margin-left: 2rem; font-size: 1.5rem; margin-bottom: 0; margin-top: 1rem; padding-bottom: 0; } .detail .content { display: block; width: 100%; height: 100%; position: fixed; top: 0; left: 0; max-width: 15000px; /* max-height: 600px; */ padding: 25px; background: #000000; color: #fff; overflow-y: scroll; } .detail .content h2 { font-size: 3rem; padding: 2rem; padding-top: 0; padding-bottom: 0.5rem; font-weight: 600; } .detail .content span { font-size: 1.4rem; margin-left: 2rem; margin-bottom: 3rem; font-weight: 300; color: #ffffff; } .detail .content .rating { margin-bottom: 30px; } .detail .content .about { display: flex; flex-wrap: wrap; margin: 0 -15px 30px; } .detail .content .about img { flex: 1 1 50%; max-width: 300px; opacity: none; padding: 0 15px; margin-left: 2rem; margin-top: 1rem; } .detail .content .about p { flex: 1 50%; padding: 15px 25px; margin-top: 3rem; font-size: 1.5rem; } .detail .content .close { /* display: inline-block; */ padding: 15px 30px; font-size: 18px; /* margin-top: 3rem; margin-right: 2rem; margin-bottom: 1rem; */ font-weight: 700; background: #223343; color: #fff; /* border-radius: 8px; */ border: none; outline: none; appearance: none; cursor: pointer; transition: 0.4s ease-out; width: 100%; display: flex; margin: auto; margin-top: 5rem; justify-content: center; align-items: center; border-radius: 5px; } .detail .content button:hover { background: #4484c4; } .detail .content .about .close:hover { background: #223343; } @media screen and (max-width: 1015px) { .results { justify-content: center; align-items: center; } .detail .content .close { width: 100%; display: flex; margin: auto; justify-content: center; align-items: center; border-radius: 5px; } } @media screen and (max-width: 683px) { .results { justify-content: center; align-items: center; } .results .result { margin: 10px; justify-content: center; align-items: center; } } @media screen and (max-width: 643px) { .results .result { margin: 15px; } } @media screen and (max-width: 638px) { .results .result { margin: 8px; } } @media screen and (max-width: 410px) { header h1 { font-size: 2.9rem; } .results { display: flex; flex-direction: column; justify-content: center; align-items: center; } .detail { overflow-y: scroll; } .detail .content .close { width: 100%; display: flex; margin: auto; justify-content: center; align-items: center; border-radius: 5px; } .detail .content span { margin-left: 0.5rem; font-style: italic; font-weight: bold; } .detail .content h2 { padding-left: 0.5rem; font-size: 2.1rem; margin-bottom: 0.5rem; font-weight: 100; } .detail .content .rating { margin-left: 0.5rem; font-weight: bold; } .detail .content .about img { margin-left: 0.5rem; } } |
Step 3: Make a new folder named Components in your src folder. In the src folder, make files – Detail.js, Result.js, Results.js, Search.js, and Search.css
Step 4: Now add the following codes in the respective files.
Detail.js
import React from "react"; function Detail({ selected, closeDetail }) { return ( <section className="detail"> <div className="content"> <h2>{selected.Title}</h2> <span>{selected.Year}</span> <p className="rating">Rating: {selected.imdbRating}</p> <div className="about"> <img src={selected.Poster} alt="" /> <p>{selected.Plot}</p> </div> <button className="close" onClick={closeDetail}> Close </button> </div> </section> ); } export default Detail; |
Result.js
import React from "react"; function Result({ result, openDetail }) { return ( <div className="result" onClick= {() => openDetail(result.imdbID)}> <img src={result.Poster} /> <h3>{result.Title}</h3> </div> ); } export default Result; |
Results.js
import React from "react"; import Result from "./Result"; function Results({ results, openDetail }) { return ( <section className="results"> {typeof results != "undefined" ? ( results.map((result) => ( <Result key={result.imdbID} result ={result} openDetail={openDetail} /> )) ) : ( <div className="not-found"> <h2>Sorry.. Movie not found in the database.</h2> <h2> Try checking the name you input or search for another movie. </h2> </div> )} </section> ); } export default Results; |
Search.js
import React from "react"; import "./Search.css"; function Search({ searchInput, search }) { return ( <div className="search-bar"> <input type="text" placeholder="Search for a Movie..." className="search" onChange={searchInput} onKeyPress={search} /> </div> ); } export default Search; |
Search.css
.search-bar { display: flex; justify-content: center; align-items: center; margin: 1rem 0; } .search { width: 60%; display: block; padding: 15px; border: none; outline: none; background: none; background-color: #fff; border-radius: 8px; color: dimgrey; font-size: 20px; font-weight: 300; transition: 0.4s ease-out; } .search:focus { box-shadow: 0 0 8px 3px #4484c4; } @media screen and (max-width: 685px) { .search { width: 75%; } } @media screen and (max-width: 410px) { .search { width: 85%; } } |
Step 5: Running and Building the application: We can run this application by using the following command. This will start React’s development server that can be used for debugging our application.
npm run start
Output: You will see the following output on your browser screen.

