如何实现点击分类组件后,在另一组件展示对应分类的电影?
当然可以动态展示!不用为每个分类单独创建组件/Action
完全没必要采用你说的那种繁琐方案——我们只需要对现有代码做几个小调整,就能让ShowGenres组件根据用户点击的分类动态加载对应电影。下面是具体的修改步骤:
1. 修复Redux Action,让它接受动态分类ID
你的selectedGenre Action已经声明了接收id参数,但API请求里硬编码了9648,我们把它改成使用传入的参数:
export const selectedGenre = (genreId) => { return dispatch => { axios.get(`https://api.themoviedb.org/3/discover/movie?api_key=<api-key>&language=en-US&include_adult=false&include_video=false&page=1&primary_release_year=2017&with_genres=${genreId}`) .then(response => { dispatch({ type:"SELECTED_GENRE", select: response.data.results }) }) .catch(err => { console.log(err); }) } }
2. 修改分类链接,传递分类ID到路由
在Genres组件里,把Link的目标路径改成带分类ID的动态路由,这样点击时就能把ID传给ShowGenres:
const mappedGenres = this.props.genres && this.props.genres.map(genre => { return ( <div className="mappedGenres" key={genre.id}> {/* 记得加key属性 */} <Link to={`/showGenres/${genre.id}`}>{genre.name}</Link> </div> ) })
同时要在你的路由配置中添加这条动态路由(假设用的是react-router-dom):
<Route path="/showGenres/:genreId" component={ShowGenres} />
3. 让ShowGenres组件读取路由参数并请求数据
修改ShowGenres组件,从路由参数中获取分类ID,然后调用Action请求对应电影。另外要注意:如果用户在ShowGenres页面直接切换不同分类的链接,需要监听路由变化重新请求数据:
import React, {Component} from "react"; import {connect} from "react-redux"; import {selectedGenre} from "./redux"; import {withRouter} from "react-router-dom"; // 引入withRouter获取路由参数 class ShowGenres extends Component { componentDidMount(){ // 从路由参数中提取分类ID const { genreId } = this.props.match.params; this.props.selectedGenre(genreId); } // 监听路由变化,切换分类时重新请求 componentDidUpdate(prevProps){ if(prevProps.match.params.genreId !== this.props.match.params.genreId){ const { genreId } = this.props.match.params; this.props.selectedGenre(genreId); } } render(){ const mappedSelected = this.props.select && this.props.select.map(movie => { return ( <div key={movie.id}> {/* 必须加key */} <h1>{movie.title}</h1> </div> ) }) return( <div> {/* 加载状态提示 */} {mappedSelected || <p>Loading movies for this genre...</p>} </div> ) } } // 用withRouter包裹,让组件能访问路由参数 export default withRouter(connect(state=> state, {selectedGenre})(ShowGenres));
4. 优化Redux Reducer,避免覆盖状态
你的当前reducer在处理SELECTED_GENRE时会覆盖整个state,导致之前的genres数据丢失。我们修改成展开原有state:
const reducer = (prevState = {}, action) => { switch(action.type){ case "DISPLAY_GENRES": return { ...prevState, genres: action.genres }; case "SELECTED_GENRE": return { ...prevState, select: action.select }; default: return prevState; } }
这样修改完成后,无论用户点击哪个分类,ShowGenres都会自动根据路由中的分类ID请求对应电影列表,完全不需要为每个分类单独写组件或Action,既简洁又高效。
内容的提问来源于stack exchange,提问作者Christian Lopez
相关产品推荐
相关产品推荐

