Mis on React?
React on populaarne JavaScripti teek, mida kasutatakse kasutajaliideste loomiseks. See põhineb komponentidel, mis võimaldab arendajatel jagada keerulised veebirakendused väikesteks taaskasutatavateks osadeks. Reacti peamine eelis on selle efektiivsus andmete uuendamisel ja kuvamisel, muutes dünaamilised veebirakendused kiireks ja sujuvaks
Mis on komponent?
See on modulaarne ja iseseisev osa rakendusest (nt nupud, menüüd, kaardid), mida saab uuesti kasutada ja mis sisaldab oma loogikat ja välimust
Milleks kasutatakse state’i?
State on objekt, mis hoiab andmeid, mis võivad rakenduse töö ajal muutuda (nt otsingusõna või filmide nimekiri). Kui state muutub, uuendab React automaatselt ekraanil olevat pilti
Miks React on kasulik?
See võimaldab luua keerulisi liideseid koodi korduvkasutamise kaudu, on väga kiire tänu Virtual DOM-ile ning omab suurt kogukonda ja ökosüsteemi.
Mõisted
JSX: JavaScripti laiendus, mis võimaldab kirjutada HTML-sarnast koodi otse JavaScripti faili.
Component: Rakenduse ehitusplokk, mis on tavaliselt JavaScripti funktsioon, mis tagastab JSX-i.
Props: Lühend sõnast properties; neid kasutatakse andmete edastamiseks ülemkomponendilt alamkomponendile.
State: Komponendi sise-mälu, mis hoiab muutuvaid andmeid ja põhjustab muutmise korral UI värskendamise.
React projekti loomine
npm create vite@latest front-end

Komponentide kasutamine React
- App.js
Rakenduse juurkomponent, mis haldab marsruutimist (routing) ja peamisi lehti (Home ja Favorites)
- MovieList.js
Üksik komponent, mis vastutab ühe filmi info (pilt, pealkiri, aasta) kuvamise ja “lemmikuks” märkimise eest.
- MovieCard.js
Halda filmide nimekirja kuvamist, andmete laadimist API-st ja otsingufunktsiooni.
Failid
Pealeht

Lemmikleht

MovieCard.jsx
Kood vastutab konkreetse filmi kaardi kuvamise ja selle lisamise eest „Lemmikute“ hulka.
Kontekstiga töötamine (globaalne seisund)
const {isFavorite, addToFavorites, removeFromFavorites} = useMovieContext()
const favorite = isFavorite(movie.id)
Nupu „Südameke” loogika
function onFavoriteClick(e) {
e.preventDefault()
if (favorite) removeFromFavorites(movie.id)
else addToFavorites(movie)
}
Täielik kood
import "../css/MovieCard.css"
import { useMovieContext } from "../contexts/MovieContext"
function MovieCard({movie}) {
const {isFavorite, addToFavorites, removeFromFavorites} = useMovieContext()
const favorite = isFavorite(movie.id)
function onFavoriteClick(e) {
e.preventDefault()
if (favorite) removeFromFavorites(movie.id)
else addToFavorites(movie)
}
return <div className="movie-card">
<div className="movie-poster">
<img src={`https://image.tmdb.org/t/p/w500${movie.poster_path}`} alt={movie.title}/>
<div className="movie-overlay">
<button className={`favorite-btn ${favorite ? "active" : ""}`} onClick={onFavoriteClick}>
♥
</button>
</div>
</div>
<div className="movie-info">
<h3>{movie.title}</h3>
<p>{movie.release_date?.split("-")[0]}</p>
</div>
</div>
}
export default MovieCard
App.jsx
See kood on rakenduse App.jsx juurkomponent, mis paneb kokku kogu programmi struktuuri, haldab lehtede vahel liikumist ja jagab andmeid.
Täielik kood
import "./css/App.css";
import Favorites from "./pages/Favorites";
import Home from "./pages/Home";
import { Routes, Route } from "react-router-dom";
import { MovieProvider } from "./contexts/MovieContext";
import NavBar from "./components/NavBar";
function App() {
return (
<MovieProvider>
<NavBar />
<main className="main-content">
<Routes>
<Route path="/" element={<Home />} />
<Route path="/favorites" element={<Favorites />} />
</Routes>
</main>
</MovieProvider>
);
}
export default App;
Home.jsx
Seisundite haldamine (useState)
const [searchQuery, setSearchQuery] = useState("");
const [movies, setMovies] = useState([]);
const [loading, setLoading] = useState(true);
Populaarsete filmide laadimine (useEffect)
useEffect(() => {
const loadPopularMovies = async () => {
const popularMovies = await getPopularMovies();
setMovies(popularMovies);
};
loadPopularMovies();
}, []);
Otsingufunktsiooni käivitamine (handleSearch)
const handleSearch = async (e) => {
e.preventDefault();
const searchResults = await searchMovies(searchQuery);
setMovies(searchResults);
};
Dünaamiline kuvamine (Konditsionaalne renderdamine)
{loading ? (
<div>Loading...</div>
) : (
<div className="movies-grid">
{movies.map((movie) => <MovieCard movie={movie} key={movie.id} />)}
</div>
)}
Täielik kood
import MovieCard from "../components/MovieCard";
import { useState, useEffect } from "react";
import { searchMovies, getPopularMovies } from "../services/api";
import "../css/Home.css";
function Home() {
const [searchQuery, setSearchQuery] = useState("");
const [movies, setMovies] = useState([]);
const [error, setError] = useState(null);
const [loading, setLoading] = useState(true);
useEffect(() => {
const loadPopularMovies = async () => {
try {
const popularMovies = await getPopularMovies();
setMovies(popularMovies);
} catch (err) {
console.log(err);
setError("Failed to load movies...");
} finally {
setLoading(false);
}
};
loadPopularMovies();
}, []);
const handleSearch = async (e) => {
e.preventDefault();
if (!searchQuery.trim()) return
if (loading) return
setLoading(true)
try {
const searchResults = await searchMovies(searchQuery)
setMovies(searchResults)
setError(null)
} catch (err) {
console.log(err)
setError("Failed to search movies...")
} finally {
setLoading(false)
}
};
return (
<div className="home">
<form onSubmit={handleSearch} className="search-form">
<input
type="text"
placeholder="Search for movies..."
className="search-input"
value={searchQuery}
onChange={(e) => setSearchQuery(e.target.value)}
/>
<button type="submit" className="search-button">
Search
</button>
</form>
{error && <div className="error-message">{error}</div>}
{loading ? (
<div className="loading">Loading...</div>
) : (
<div className="movies-grid">
{movies.map((movie) => (
<MovieCard movie={movie} key={movie.id} />
))}
</div>
)}
</div>
);
}
export default Home;

