• 搜索电影小demo-react版(10.5-10.6)


    通过这个小例子学习了react的哪些知识?

    1. 钩子 useState 相当于state和setState ,写法 const [searchValue, setSearchValue] = useState(""),

    2. 钩子 useReducer, 在 hooks 中提供了的 useReducer 功能,可以增强 ReducerDemo 函数提供类似 Redux 的功能,引入 useReducer 后,useReducer 接受一个 reducer 函数作为参数,reducer 接受两个参数一个是 state 另一个是 action 。然后返回一个状态 count 和 dispath,count 是返回状态中的值,而 dispatch 是一个可以发布事件来更新 state 的。

    3. 钩子 useEffect 使用useEffect,可以直接在函数组件内处理生命周期事件。 如果你熟悉 React class 的生命周期函数,你可以把 useEffect Hook 看做 componentDidMountcomponentDidUpdate 和 componentWillUnmount 这三个函数的组合

    4. 例子用组件可以拆分为头部组件/搜索组件/电影组件
    其中头部组件只需要接收demo的标题
    import React from 'react'
    const Header = (props) => {
      return(
        <header className="App-header">
          <h2>{props.text}</h2>
        </header>
      )
    }
    export default Header
    其中搜索组件需要做的事情(由一个搜索框和按钮组成),用到了useState钩子作用是重置或输入框改变时改变state里的值,还有向父组件传事件时会用到props,如点击了搜索props.search(searchValue),searchValue取的就是state里的值, 包住方法用{},input的值value就可以,需要用form表单来包住具体代码如下:
    import React, { useState } from "react";
    const Search = (props) => {
      const [searchValue, setSearchValue] = useState("")
      // 当输入框改变时调用
      const handleSearchInputsChange = (e) => {
        setSearchValue(e.target.value);
      }
      // 重置
      const resetInputField = () => {
        setSearchValue("");
      }
      const callSearchFunction = (e) => {
        e.preventDefault(); // 阻止事件的默认点击事件执行
        props.search(searchValue);
        resetInputField();
      }
      return (
        <form className="search">
          <input
            value={searchValue}
            onChange={handleSearchInputsChange}
            type="text"
          ></input>
          <input onClick={callSearchFunction} type="submit" value="SEARCH"></input>
        </form>
      )
    }
    export default Search
     
    其中电影组件需要做的事情,设置无网时或者说是默认图片,设置电影名字和介绍等
    import React from "react";
    
    const DEFAULT_PLACEHOLDER_IMAGE =
      "https://m.media-amazon.com/images/M/MV5BMTczNTI2ODUwOF5BMl5BanBnXkFtZTcwMTU0NTIzMw@@._V1_SX300.jpg";
    
    
    const Movie = ({ movie }) => {
      const poster =
        movie.Poster === "N/A" ? DEFAULT_PLACEHOLDER_IMAGE : movie.Poster;
      return (
        <div className="movie">
          <h2>{movie.Title}</h2>
          <div>
            <img
              width="200"
              alt={`The movie titled: ${movie.Title}`}
              src={poster}
            />
          </div>
          <p>({movie.Year})</p>
        </div>
      );
    };
    
    
    export default Movie;
    app.js需要把上面三个组件集成起来,react原生是支持fetch请求的,加载电影资源时分为三种情况,请求时/请求成功/请求失败
    请求时,需要加载loading/请求成功需要给电影子组件传递电影数据,loading消失/请求失败loading消息,提示错误消息,具体代码如下:
    import Header from './Header';
    import Search from './Search'
    import Movie from './Movie'
    import './App.css';
    import React, { useReducer, useEffect } from 'react';
    // 电影api
    const MOVIE_API_URL = "https://www.omdbapi.com/?s=man&apikey=4a3b711b"; 
    
    const initialState = {
      loading: true,
      movies: [],
      errorMessage: null
    }
    // 三个状态 SEARCH_MOVIES_REQUEST/SEARCH_MOVIES_SUCCESS/SEARCH_MOVIES_FAILURE
    const reducer = (state, action) => {
      switch(action.type) {
        case 'SEARCH_MOVIES_REQUEST':
          return {
            ...state,
            loading: true,
            errorMessage: null
          }
          case 'SEARCH_MOVIES_SUCCESS':
            return {
              ...state,
              loading: false,
              movies: action.playload
            }
          case 'SEARCH_MOVIES_FAILURE':
            return {
              ...state,
              loading: false,
              errorMessage: action.error
            }
          default:
        return state;
      }
    }
    // 无关键字或错误数据 {"Response":"False","Error":"Incorrect IMDb ID."}
    const App = () => {
      // 设置state状态
      // const [loading, setLoading] = useState(true)
      // const [movies, setMovies] = useState([])
      // const [errorMessage, setErrorMessage] = useState(null)
      // useEffect(() => {
      //   fetch(MOVIE_API_URL)
      //   .then(response => response.json())
      //   .then(jsonResPonse => {
      //     setLoading(false);
      //     setMovies(jsonResPonse.Search);
      //   })
      // }, [])
      // const search = searchValue => {
      //   setLoading(true);
      //   setErrorMessage(null);
      //   fetch(`https://www.omdbapi.com/?s=${searchValue}&apikey=4a3b711b`)
      //   .then(response => response.json())
      //   .then(jsonResponse => {
      //     if (jsonResponse.Response === 'True') {
      //       setLoading(false);
      //       setMovies(jsonResponse.Search);
      //     } else {
      //       setLoading(false);
      //       setErrorMessage(jsonResponse.Error);
      //     }
      //   })
      // }
      // 用useReducer替换useState
      const [state, dispatch] = useReducer(reducer, initialState);
        useEffect(() => {
          fetch(MOVIE_API_URL)
          .then(response => response.json())
          .then(jsonResPonse => {
            dispatch({
              type: 'SEARCH_MOVIES_SUCCESS',
              playload: jsonResPonse.Search 
            })
          })
        }, [])
       const search = searchValue => {
        dispatch({
          type: "SEARCH_MOVIES_REQUEST"
        });
        // setLoading(true);
        // setErrorMessage(null);
        fetch(`https://www.omdbapi.com/?s=${searchValue}&apikey=4a3b711b`)
        .then(response => response.json())
        .then(jsonResponse => {
          if (jsonResponse.Response === 'True') {
            // setLoading(false);
            // setMovies(jsonResponse.Search);
            dispatch({
              type: 'SEARCH_MOVIES_SUCCESS',
              playload: jsonResponse.Search 
            });
          } else {
            // setLoading(false);
            // setErrorMessage(jsonResponse.Error);
            dispatch({
              type: 'SEARCH_MOVIES_FAILURE',
              errorMessage: jsonResponse.Error 
            });
          }
        })
      }
      const { movies, loading, errorMessage } = state;
      return (
        <div className="App">
          <Header text="HOOKED"/>
          <Search search={search}/>
          <p className="App-intro">Sharing a few of our favourite movies</p>
          <div className="movies">
            {
              loading && !errorMessage ? (<span>...loading</span>) : errorMessage ? (<div className="errorMessage">{errorMessage}</div>)
              : (movies.map((movie, index) => (
                <Movie key={`${index}-${movie.title}`} movie={movie}/>
              )))
            }
          </div>
        </div>
      );
    }
    
    export default App;
    最后详细教程介绍请参考下面的网站

     参考网站链接: https://www.freecodecamp.org/news/how-to-build-a-movie-search-app-using-react-hooks-24eb72ddfaf7/

    将来的自己,会感谢现在不放弃的自己!
  • 相关阅读:
    ffmpeg用法
    文本文件存储格式
    一个守护进程实例
    构造函数初始化列表问题
    Windows系统下远程Linux系统
    printStackTrace
    getParameter
    HTML5新增的属性和废除的属性
    oracle导出表结构及注释
    <input type="text" > size与width区别
  • 原文地址:https://www.cnblogs.com/TheYouth/p/15370934.html
Copyright © 2020-2023  润新知