React中如何按属性过滤对象?实现排除参考对象的推荐功能
解决React中同类型电影推荐筛选时包含当前影片的问题
问题根源分析
你遇到的问题主要有三个核心点:
- 未排除当前影片:原filter逻辑仅匹配类型,未加入排除当前电影的判断条件
- 变量名拼写错误:电影数组定义的是
genre字段,但渲染和筛选时误用了genrer,会导致字段读取失败 - 数据结构缺失:原电影数组没有唯一
id字段,find方法无法正确定位当前电影
修正方案
1. 完善电影数据结构
给每个电影对象添加唯一id,确保find和筛选逻辑能精准识别影片:
const movies = [ { id: 1, title: 'Movie 1', genre: 'horror, suspense', rating: '8.2', type: 'Movie', duration: '1h45m', sinopsis: '...', cover: '...' }, { id: 2, title: 'Movie 2', genre: 'drama, futuristic', rating: '7.5', type: 'Movie', duration: '2h10m', sinopsis: '...', cover: '...' }, { id: 3, title: 'Movie 3', genre: 'horror, gore', rating: '6.8', type: 'Movie', duration: '1h30m', sinopsis: '...', cover: '...' }, { id: 4, title: 'Movie 4', genre: 'action, gore', rating: '7.9', type: 'Movie', duration: '1h55m', sinopsis: '...', cover: '...' }, ];
2. 正确的筛选逻辑
同时实现同类型匹配(支持多类型交集)和排除当前影片:
// 获取当前展示的电影对象 const movie = movies.find(movie => movie.id === parseInt(id)); // 拆分当前电影的类型为数组并去除空格 const currentGenres = movie.genre.split(',').map(g => g.trim()); // 筛选推荐影片 const recommendedMovies = movies.filter(m => { // 直接排除当前电影 if (m.id === movie.id) return false; // 拆分遍历影片的类型 const movieGenres = m.genre.split(',').map(g => g.trim()); // 检查是否有至少一个共同类型 return currentGenres.some(genre => movieGenres.includes(genre)); });
3. 修正组件中的拼写错误
将渲染部分的movie.genrer改为movie.genre,保证字段读取正确:
<p><strong>Genre: </strong>{movie.genre}</p>
4. 传递推荐影片给SubRow组件
<SubRow recomended={recommendedMovies}></SubRow>
完整修正后的组件代码
import { useParams } from "react-router-dom"; import movies from '../data/dataAll'; import SubRow from "./SubRow"; import './MovieDetails.css' const MovieDetails = () => { const { id } = useParams(); const movies = [ { id: 1, title: 'Movie 1', genre: 'horror, suspense', rating: '8.2', type: 'Movie', duration: '1h45m', sinopsis: 'A thrilling horror story...', cover: '/path/to/cover1.jpg' }, { id: 2, title: 'Movie 2', genre: 'drama, futuristic', rating: '7.5', type: 'Movie', duration: '2h10m', sinopsis: 'A futuristic drama...', cover: '/path/to/cover2.jpg' }, { id: 3, title: 'Movie 3', genre: 'horror, gore', rating: '6.8', type: 'Movie', duration: '1h30m', sinopsis: 'A gory horror film...', cover: '/path/to/cover3.jpg' }, { id: 4, title: 'Movie 4', genre: 'action, gore', rating: '7.9', type: 'Movie', duration: '1h55m', sinopsis: 'An action-packed gore fest...', cover: '/path/to/cover4.jpg' }, ]; const movie = movies.find(movie => movie.id === parseInt(id)); const currentGenres = movie.genre.split(',').map(g => g.trim()); const recommendedMovies = movies.filter(m => { if (m.id === movie.id) return false; const movieGenres = m.genre.split(',').map(g => g.trim()); return currentGenres.some(genre => movieGenres.includes(genre)); }); return ( <div className=" bg-wrapper moviedetails"> <div className="moviedetails-content bg-wrapper-content"> <div className="moviedetails-content-info "> <h2 className="movie-title">{movie.title}</h2> <div className="movie-tags"> <span>{movie.rating}</span> <span>{movie.type}</span> <span>{movie.duration}</span> </div> <p className="movie-base">{movie.sinopsis}</p> <hr className="line"/> <p><strong>Genre: </strong>{movie.genre}</p> </div> </div> <div className="banner-background bg-wrapper-image" style={{ backgroundImage: `url(${movie.cover})` }} ></div> <SubRow recomended={recommendedMovies}></SubRow> </div> ); } export default MovieDetails;
关键说明
- 排除当前影片:通过
m.id === movie.id直接过滤当前电影,这是解决结果包含当前影片的核心 - 多类型匹配:用
split拆分类型字符串,some+includes检查类型交集,适配多类型标签的场景 - 变量名一致性:统一使用
genre字段名,避免拼写错误导致的无数据问题
内容的提问来源于stack exchange,提问作者Luis Hernandez
相关产品推荐
相关产品推荐

