如何在Redux中为数组添加唯一元素?电影收藏功能故障求助
问题分析与解决方案
首先看你的代码里有两个关键问题导致功能失效:
1. 状态属性名拼写不一致
你的初始状态里定义的是favouriteMovies,但在reducer的case分支里却用了favouritesMovies(多了一个s),这会导致你始终无法正确访问到收藏列表数组,自然无法完成重复判断和添加操作。
2. 对象无法用indexOf判断存在性
action.favMovie是一个对象,而indexOf使用**严格相等(===)**来匹配元素。对于对象来说,即使两个对象的内容完全一致,只要它们是不同的引用,indexOf就会返回-1,这会导致你每次都认为电影不存在,重复添加。我们需要通过对象的唯一标识(比如电影的id)来判断是否已经在收藏列表中。
修正后的Reducer代码
const initialState = { favouriteMovies: [] }; const favMoviesReducer = (state = initialState, action) => { switch (action.type) { case actionTypes.GET_FAV_MOVIES: // 检查收藏列表中是否已存在该电影(通过唯一id判断) const isMovieExists = state.favouriteMovies.some( movie => movie.id === action.favMovie.id ); if (!isMovieExists) { return { // 保持原状态不变,仅更新收藏列表 ...state, favouriteMovies: [...state.favouriteMovies, action.favMovie] }; } // 如果已存在,直接返回原状态 return state; default: return state; } };
关键说明:
- 属性名统一:把所有引用收藏列表的地方都改成
favouriteMovies,和初始状态保持一致。 - 用
some判断对象存在:some方法会遍历数组,只要有一个元素满足movie.id === action.favMovie.id就返回true,这样就能准确判断电影是否已被收藏(前提是你的电影对象有唯一的id属性,如果是其他唯一标识,替换成对应的字段即可)。 - 不可变更新状态:返回新的状态对象时,先展开原状态
...state,再更新favouriteMovies数组,这符合Redux对状态不可变的要求。
内容的提问来源于stack exchange,提问作者Ahmed Eid
相关产品推荐
相关产品推荐

