搜索电影小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 看做 componentDidMount,componentDidUpdate 和 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/
将来的自己,会感谢现在不放弃的自己!

浙公网安备 33010602011771号