React

Sissejuhatus ja arusaamine

Mis on React?

React on JavaScripti teekе, millega tehakse veebilehtede välimust ja sisu. See koosneb väikestest tükkidest, mida saab uuesti kasutada, et ehitada suuri ja kiireid lehti. React aitab veebilehel muutuda kohe, kui kasutaja midagi teeb, ilma et peaks tervet lehte uuesti laadima.

Mis on komponent?

Komponent on iseseisev ja taaskasutatav koodiosa (tavaliselt funktsioon), mis juhib teatud osa ekraanist, näiteks nuppu või sisestusvälja.

Milleks kasutatakse state’i?

State on komponendi seesmine mälu, mis salvestab muutuvaid andmeid ja uuendab automaatselt vaadet, kui need andmed muutuvad.

Miks React on kasulik veebirakenduste tegemiseks?

React muudab arenduse süsteemseks, võimaldab koodi uuesti kasutada ja tagab rakenduse sujuva töö ka suurte andmehulkade puhul.

Põhimõisted:

  • JSX – JavaScripti laiendus, mis lubab kirjutada HTML-i sarnast koodi otse JavaScripti failis.
  • Component – rakenduse baasühik, mis määrab ära ühe liidese osa välimuse ja loogika.
  • Props – atribuudid, mille abil saadetakse andmeid ühelt komponendilt teisele.
  • State – objekti kujul andmehoidla, mis jälgib komponendi hetkeseisu ja reageerib muudatustele.

React Movie projekt

React projekti loomine

Installi Node.js.
Ava terminal ja kirjuta järgmine käsklus uue projekti algatamiseks:

npx create-next-app@latest
npx create-react-app react-app
cd react-app

Käivitage projekt:

npm start

Ava localhost:3000 brauseris.

Komponentide kasutamine

index.js ja App.js

See on rakenduse käivituspunkt, mis ühendab koodi veebilehega ja määrab üldise struktuuri.

Eesmärk:

  • Seob Reacti rakenduse HTML-faili ‘root’ elemendiga.
  • Ümbritseb rakenduse BrowserRouter-iga, et lehtede vahel liikumine toimiks.
  • Pakub andmete konteksti (MovieProvider).
  • Kuvab igal lehel nähtavat navigatsiooniriba (NavBar) ja jalust.
  • Määrab marsruudid (Routes), et näidata sisu vastavalt aadressile (Avaleht või Lemmikud).
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
  <React.StrictMode>
    <BrowserRouter>
      <App />
    </BrowserRouter>
  </React.StrictMode>
);
function App()
{
	return (
		<MovieProvider>
			<NavBar />
			<main className="main-content">
				<Routes>
					<Route path="/" element={<Home />} />
					<Route path="/favorites" element={<Favorites />} />
				</Routes>
			</main>
			<footer className="footer">
				<p>&copy; 2026 Movie App. All rights reserved.</p>
			</footer>
		</MovieProvider>
	);
}

Home.jsx

See on rakenduse põhikuva, mis vastutab filmide otsimise ja populaarsete filmide nimekirja kuvamise eest.

Eesmärk:

  • Kasutab olekuid (useState), et hoida otsingusõna, filmide nimekirja, laadimisolekut ja vigu.
  • Rakenduse käivitumisel laeb useEffect abil automaatselt populaarsed filmid.
  • Funktsioon handleSearch teostab filmide otsingu vastavalt kasutaja sisestatud märksõnale.
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>
  );
}

MovieCard.jsx

See komponent vastutab üksiku filmi kaardi kuvamise ja selle lemmikute haldamise eest.

Eesmärk:

  • Suhtleb MovieContext-iga, et kontrollida, kas film on lemmikute nimekirjas, ning lisada või eemaldada see sealt.
  • Funktsioon onFavoriteClick võimaldab kasutajal ühe klikiga lisada filmi lemmikute hulka või sealt eemaldada.
  • Näitab filmi postrit, pealkirja ja väljalaske aastat.
  • Lisab lemmikute nupule klassi active, kui film on märgitud lemmikuks, andes kasutajale kohest visuaalset tagasisidet.
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>
}

State’i kasutamine

Reactis tähistab state komponendi dünaamilist mälu, mille muutumine paneb rakenduse sisu automaatselt uuenema.

Selles vaates kasutatakse useState funktsiooni nelja põhilise asja kontrollimiseks:

  • Päring – salvestab trükitud otsingusõna.
  • Filmid – hoiab API-st laetud andmete massiivi.
  • Vead – teavitab ebaõnnestunud andmepärimisest.
  • Laadimine – näitab, kas sisu on veel saabumas.
  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();
  }, []);

Filmide laadimine API abil

Andmed tulevad TMDB andmebaasist. Turvalisuse huvides on unikaalne API-võti peidetud .env faili.

const API_KEY = process.env.REACT_APP_API_KEY;
const BASE_URL = "https://api.themoviedb.org/3";

export const getPopularMovies = async () => {
	const response = await fetch(`${BASE_URL}/movie/popular?api_key=${API_KEY}`);
	const data = await response.json();
	return data.results || [];
};

Otsingufunktsiooni lisamine

Otsing võimaldab kasutajal filtreerida kuvatavat sisu. See funktsioon tegeleb päringu saatmise ja tulemuste haldamisega.

Funktsiooni sammud:

  • Kontrolle.preventDefault() peatab lehe värskendamise. Kui otsingukast on tühi või laadimine juba käib, siis funktsioon katkestatakse.
  • Päring – Käivitatakse setLoading(true) ja oodatakse vastust funktsioonilt searchMovies(searchQuery).
  • Tulemused – Eduka päringu korral uuendatakse filmide nimekirja (setMovies) ja eemaldatakse veateated.
  • Veatöötlus – Vea korral kuvatakse teade “Failed to search movies…”.
  • Lõpetaminefinally plokis lülitatakse laadimisolek alati välja.
  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)
    }
  };

Tulemus

Github