返回

电影信息网站:使用React Hooks实现电影查询和展示

前端

引子

欢迎来到React Hooks电影信息网站教程。在这个教程中,我们将创建一个React网站,用户可以通过该网站查询和浏览电影信息。我们将会使用React Hooks来管理状态、处理异步请求和构建交互式界面。

项目结构

我们的项目将由以下几个主要组件组成:

  • 电影查询组件:该组件允许用户输入电影名称进行查询。
  • 电影列表组件:该组件显示查询结果的电影列表。
  • 电影详情组件:该组件显示选定电影的详细信息。

实现步骤

  1. 创建React项目
npx create-react-app movie-search
  1. 安装必要的依赖项
npm install axios react-router-dom
  1. 创建组件

src目录下创建以下组件:

  • MovieSearch.js:电影查询组件
  • MovieList.js:电影列表组件
  • MovieDetails.js:电影详情组件
  1. 实现电影查询组件

MovieSearch.js组件中,我们使用useStateuseEffect钩子来管理电影查询的状态和处理异步请求。

import React, { useState, useEffect } from "react";
import axios from "axios";

const MovieSearch = () => {
  const [query, setQuery] = useState("");
  const [movies, setMovies] = useState([]);
  const [loading, setLoading] = useState(false);

  useEffect(() => {
    const fetchMovies = async () => {
      setLoading(true);
      const response = await axios.get(
        `https://www.omdbapi.com/?s=${query}&apikey=YOUR_API_KEY`
      );
      setMovies(response.data.Search);
      setLoading(false);
    };

    if (query) {
      fetchMovies();
    }
  }, [query]);

  return (
    <div>
      <input
        type="text"
        placeholder="Search for a movie..."
        value={query}
        onChange={(e) => setQuery(e.target.value)}
      />
      {loading ? <p>Loading...</p> : <MovieList movies={movies} />}
    </div>
  );
};

export default MovieSearch;
  1. 实现电影列表组件

MovieList.js组件中,我们使用useEffect钩子来处理异步请求,并使用useReducer钩子来管理电影列表的状态。

import React, { useEffect, useReducer } from "react";
import { Link } from "react-router-dom";

const reducer = (state, action) => {
  switch (action.type) {
    case "ADD_MOVIE":
      return [...state, action.movie];
    case "REMOVE_MOVIE":
      return state.filter((movie) => movie.imdbID !== action.movie.imdbID);
    default:
      return state;
  }
};

const MovieList = ({ movies }) => {
  const [state, dispatch] = useReducer(reducer, []);

  useEffect(() => {
    dispatch({ type: "ADD_MOVIE", movie: movies });
  }, [movies]);

  return (
    <ul>
      {state.map((movie) => (
        <li key={movie.imdbID}>
          <Link to={`/movies/${movie.imdbID}`}>{movie.Title}</Link>
        </li>
      ))}
    </ul>
  );
};

export default MovieList;
  1. 实现电影详情组件

MovieDetails.js组件中,我们使用useEffect钩子来处理异步请求,并使用useState钩子来管理电影详情的状态。

import React, { useEffect, useState } from "react";
import axios from "axios";

const MovieDetails = ({ match }) => {
  const [movie, setMovie] = useState({});
  const [loading, setLoading] = useState(false);

  useEffect(() => {
    const fetchMovie = async () => {
      setLoading(true);
      const response = await axios.get(
        `https://www.omdbapi.com/?i=${match.params.id}&apikey=YOUR_API_KEY`
      );
      setMovie(response.data);
      setLoading(false);
    };

    fetchMovie();
  }, [match.params.id]);

  return (
    <div>
      {loading ? <p>Loading...</p> : <pre>{JSON.stringify(movie, null, 2)}</pre>}
    </div>
  );
};

export default MovieDetails;
  1. 配置路由

App.js组件中,我们使用BrowserRouterRoute组件来配置路由。

import React from "react";
import { BrowserRouter as Router, Route } from "react-router-dom";
import MovieSearch from "./MovieSearch";
import MovieList from "./MovieList";
import MovieDetails from "./MovieDetails";

const App = () => {
  return (
    <Router>
      <div>
        <MovieSearch />
        <Route exact path="/" component={MovieList} />
        <Route path="/movies/:id" component={MovieDetails} />
      </div>
    </Router>
  );
};

export default App;
  1. 运行项目
npm start

结语

在这个教程中,我们使用React Hooks构建了一个电影查询网站。我们学习了如何使用useState、useEffect和useReducer钩子来管理状态、处理异步请求和构建交互式界面。我希望这个教程对您有所帮助。