我正在尝试使用useEffect,就像在类组件中使用componentDidMount和componentDidUpdate一样。因此,我有一个名为SeasonPage的组件,并且该组件内部是指向具有不同参数的同一组件的链接。但是,当url更改其参数时,该组件不会重新呈现我在useEffect中调用的函数。最初我有一个空的依赖项数组,但是经过一番研究,我添加了props.match.params.seasonid
但还是没有运气。我希望有人能展示使用钩子执行此任务的正确方法。
谢谢,
export default function SeasonPage(props) {
const [season, setSeason] = useState({});
const [seasonID, setSeasonID] = useState(props.match.params.seasonid);
const [showID] = useState(props.match.params.id);
const [episodes, setEpisodes] = useState([]);
const [show, setShow] = useState({});
const [otherSeasons, setOtherSeasons] = useState([]);
useEffect(() => {
getShow();
getSeasons();
console.log(props);
},[props.match.params.seasonid]);
const getShow = () =>{
axios.get(`https://api.themoviedb.org/3/tv/${showID}?api_key=apikey&language=en-US`)
.then(results => {
setShow(results.data)
setOtherSeasons(results.data.seasons)
})
.catch(error =>{
console.log(error)
});
}
const getSeasons = () =>{
axios.get(`https://api.themoviedb.org/3/tv/${showID}/season/${seasonID}?api_key=apikey&language=en-US`)
.then(results =>{
console.log(results);
setSeason(results.data);
setEpisodes(results.data.episodes)
})
.catch(error =>{
console.log(error);
});
};
const handleError = (e) =>{
console.log(e);
e.target.src = 'https://upload.wikimedia.org/wikipedia/commons/thumb/a/ac/No_image_available.svg/300px-No_image_available.svg.png';
}
let episodesjsx = episodes.map((ep, i) =>{
return <MovieCard movie={ep} key={i} id={ep.id} title={ep.name} overview={ep.overview} voteAverage={ep.vote_average} backdropPath={ep.still_path} type="episode"/>;
});
let otherSeasonsjsx = otherSeasons.map(seasonx => {
return seasonx.season_number !== parseInt(seasonID )&& <SeasonsCard season={seasonx} tvshowID={show.id} />
});
return (
<div className="season-page">
<div className="container">
<div className="banner" style={{backgroundImage:`url("https://image.tmdb.org/t/p/original/${show.backdrop_path}")`}}>
<div className="banner-overlay">
<div className="banner-content">
<div className="banner-content-poster-div">
<img src={`https://image.tmdb.org/t/p/w342/${season.poster_path}`}></img>
</div>
<div className="banner-content-details">
<h1>{show.name}</h1>
<h3>{season.name}</h3>
<p>{season.air_date}</p>
<div className="overview">
<p>{season.overview}</p>
</div>
</div>
</div>
</div>
</div>
<div className="scroll-container-div">
<h2>{season.name} Episodes</h2>
<div className="scroll-div">
{episodesjsx}
</div>
</div>
<div className="scroll-container-div">
<h2>Other Seasons</h2>
<div className="scroll-div">
{otherSeasonsjsx}
</div>
</div>
</div>
</div>
)
}
下面是具有按钮的组件,该按钮可链接到要渲染的相同组件。
const useStyles = makeStyles({
root: {
maxWidth: 345,
minWidth: 325,
margin: '15px',
},
media: {
height: 250,
objectFit: 'cover',
},
});
export default function SeasonCard(props) {
const classes = useStyles();
const description = props.overview ? props.overview.slice(0, 120) + "...": '';
let pic = `https://image.tmdb.org/t/p/original/${props.season.poster_path}`;
return (
<Card className={classes.root}>
<CardActionArea>
<CardMedia
className={classes.media}
component="img"
alt={props.season.name}
image={pic}
title={props.season.name}
/>
<CardContent>
<Typography gutterBottom variant="h5" component="h2">
{props.season.name} ({props.season.episode_count} ep.)
</Typography>
<Typography variant="body2" color="textSecondary" component="p">
{description}
</Typography>
</CardContent>
</CardActionArea>
<CardActions>
<Button size="small" color="primary" component={Link} to={`/tvshows/${props.tvshowID}/seasons/${props.season.season_number}`} style={{width: '100px'}}>
Learn More
</Button>
</CardActions>
</Card>
);
}
这是我的路由器,以备您需要时使用。
<Route path="/tvshows/:id/seasons/:seasonid" component={SeasonPage} ></Route>
答案 0 :(得分:0)
我认为这些说法不对。 道具与状态的同步是一种反模式。(More on this)
const [seasonID, setSeasonID] = useState(props.match.params.seasonid);
const [showID] = useState(props.match.params.id);
相反,直接从道具中获取ID。
useEffect(() => {
getShow();
getSeasons();
console.log(props);
}, [props.match.params]); //excecute code whenever id and/or seasonid changed
const getShow = () => {
const { id } = props.match.params;
axios.get(`https://api.themoviedb.org/3/tv/${id}?api_key=apikey&language=en-US`)
.then(results => {
setShow(results.data)
setOtherSeasons(results.data.seasons)
})
.catch(error => {
console.log(error)
});
}
const getSeasons = () => {
const { id, seasonid } = props.match.params;
axios.get(`https://api.themoviedb.org/3/tv/${id}/season/${seasonid}?api_key=apikey&language=en-US`)
.then(results => {
console.log(results);
setSeason(results.data);
setEpisodes(results.data.episodes)
})
.catch(error => {
console.log(error);
});
};