我正處于學習階段,所以如果有什么不合邏輯的地方,請告訴我。我一直在嘗試以一種方式使用顯示結果,默認情況下,用戶應該看到趨勢 API 結果,當他開始使用搜索查詢搜索其他 API 時,將觸發或被呼叫。我嘗試使用 if-else 但沒有結果。它顯示空白。我不知道我怎樣才能實作它。如果你能幫我解決這個問題,我將不勝感激。
當我獲得資料時,我會在下面的卡片中顯示該資料,正如您將使用地圖功能看到的那樣,如果搜索為空白,我會嘗試顯示錯誤。但正如您在影像中看到的那樣,我得到了一張空白卡。我該如何解決這個問題?

請參閱我嘗試過的代碼。我不知道這是否合乎邏輯。預先感謝一百萬。
import React ,{useEffect, useState} from 'react';
import {Grid, Button, Card, CardActionArea, CardActions, CardContent, CardMedia, Typography, makeStyles } from '@material-ui/core';
import Rating from '@material-ui/lab/Rating';
import Watchlist from '../Products/Watchlist.jsx';
import Error from '../Error/Error.jsx';
const useStyles = makeStyles (theme => ({
cardButton:{
'&:hover':{
backgroundColor:'#356E44',
color: 'white',
}
},
Main:{
width: "100vw",
justifyContent: " flex-start",
display: "flex",
flexWrap: "wrap",
alignItems: "stretch",
alignContent: " flex-start",
columnGap: "20px",
rowGap:"5px",
},
cardMain:{
width: 'min-content',
height: 'min-content',
margin: '10px',
'&:hover':{
boxShadow: '5px 3px 5px white',
}
},
cardImage:{
height: '150px',
marginLeft: '7px',
marginRight: '7px',
marginTop: '5px',
objectFit: 'cover',
},
cardContent: {
width: '250px',
height: '50px',
wordBreak: 'break-word',
fontSize: '1rem',
fontWeight: 'bolder',
},
typography1:{
float: 'right',
},
typography2:{
float: 'left',
},
}));
const Produts = (props) =>{
const classes = useStyles();
const [movieData, setMovieData] = useState([]);
const [watchlist, setWatchlist] = useState ([]);
const filterData = ((val) => {
const keyword = props.searchText;
if (keyword !== "") {
return val
}
else if (val.original_title?.toLowerCase().includes(props.searchText?.toLowerCase())) {
return val
}
} );
useEffect (()=> {
const getMovieList = async () => {
const TrendingUrl = 'https://api.themoviedb.org/3/trending/all/day?api_key=API_keyID' ;
const allResultsUrl = `http://api.themoviedb.org/3/search/movie?api_key=API_keyID&query=${props.searchText}`;
const response = await fetch (props.searchText ? TrendingUrl : allResultsUrl);
try {
const responseJson = await response.json();
const data = (responseJson.results);
setMovieData(data);
console.log(data)
} catch (err) {
console.error(err);
}
};
getMovieList();
}, [props.searchText]);
const handleWatchlist = (movieData) => {
const newWatchlist = [...watchlist , movieData];
setWatchlist (newWatchlist);
}
return (
<>
<Grid
item
xs
container
direction="column"
justifyContent="flex-start"
alignItems="flex-start"
style={{ backgroundColor: "black", width: "100%", height: "100%"}}
>
<div className ={classes.Main} > { movieData.length === 0 ? (<h1 style = {{color: 'red', fontSize : "2rem"}}>No search results found</h1>)
: movieData.filter(filterData).map((movie) =>{
return(
<Card className={classes.cardMain} key={movie.id}>
<CardActionArea>
<CardMedia className = {classes.cardImage}>
<img style = {{width: '100%', height: '100%', objectFit: 'cover'}}
src ={`https://image.tmdb.org/t/p/original${movie.poster_path}`}
alt = "movie poster"/>
</CardMedia>
<CardContent className = {classes.cardContent}>
<Typography> {movie.original_title} </Typography>
<Typography
className = {classes.typography1}
variant="body2"
component = "p"
> {movie.release_date}
</Typography>
<Rating
className = {classes.typography2}
name = "ratings"
value = {movie.vote_average/2}
precision={0.5}
readOnly
/>
</CardContent>
</CardActionArea>
<CardActions style = {{justifyContent: 'space-evenly'}} >
<Button className = {classes.cardButton} size = "small">Watch</Button>
<Button className = {classes.cardButton} size = "small" >Share</Button>
<Button className = {classes.cardButton}size = "small" onClick = { () => handleWatchlist(movie) }> Add </Button>
</CardActions>
</Card>
);
})}
</div>
</Grid>
</>
)
};
export default Produts;
uj5u.com熱心網友回復:
我將把 API 一分為二。此外,稍微重命名變數以獲得更好的命名約定。
const fetchTrending = () => {
const url = 'https://api.themoviedb.org/3/trending/all/day?api_key=api_keyID';
fetch(url)
.then(response => response.json())
.then(trendingMovies => setMovies(trendingMovies))
.catch(error => {
// TODO: Do your error handling here
console.error(error);
});
};
const fetchQuery = search => {
const url = `http://api.themoviedb.org/3/search/movie?api_key=api_keyID&query=${search}`;
fetch(url)
.then(response => response.json())
.then(queriedMovies => setMovies(queriedMovies))
.catch(error => {
// TODO: Do your error handling here
console.error(error);
});
};
/* When the component is mounted, load trending movies
This will only run once.
*/
useEffect(() => fetchTrending(), []);
// pass this handler to the onChange listener of your search field
const handleSearchChange = search => fetchQuery(search);
uj5u.com熱心網友回復:
我想這可能對你有幫助。我經常使用這個小鉤子來做這樣的事情。
它的作業原理與 useMemo 相同,但允許您傳遞一個回傳承諾的回呼,而不是立即回傳一個值。
像這樣使用它:
import { usePromiseMemo } from 'usePromiseMemo';
function MyComponent() {
const movieData = usePromiseMemo(
() =>
fetch(
props.searchText
? `http://api.themoviedb.org/3/search/movie?api_key=api_keyID&query=${props.searchText}`
: `https://api.themoviedb.org/3/trending/all/day?api_key=api_keyID`
)
.then(r => r.json())
.then(r => {
console.log('Raw data: ', r);
const data = r.results;
console.log('Data: ', data);
return data;
})
.catch(err => {
console.log(err);
}),
[props.searchText]
);
return <></>;
}
另外,您從“原始資料”日志中得到了什么?
uj5u.com熱心網友回復:
你確定src圖片是正確的嗎?這似乎是一個奇怪的模式。
應該是 https://image.tmdb.org/t/p/original/${movie.poster_path}而不是https://image.tmdb.org/t/p/original${movie.poster_path}?在original和之間標記“/”${movie.poster_path}
編輯:如檔案中所示。
uj5u.com熱心網友回復:
謝謝您的幫助。上面的代碼是使用條件運算子呼叫 api 的正確答案。但是,為什么我看不到結果是因為我的 useState 鉤子沒有空字串的初始值,因此它顯示為 undefined: Code before:
const[searchText, setSearchText] = useState();
經過一番閱讀和逐行查看后,我發現
它應該如下所示,這是一個適當的空字串。
const[searchText, setSearchText] = useState("");
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/337386.html
標籤:javascript 反应 接口 休息 反应还原
下一篇:[Git系列] Git 基本概念
