【发布时间】:2020-04-23 01:43:46
【问题描述】:
我目前是基于 react-redux 的 React SPA 应用程序。在 reducer.js 中,我有两个主要状态,即 mylist 和 Recommendations。我附上了两张实际应用的图片。有两页。第一个是主页,其中有三个电影的初始推荐。在每部电影下面都有一个添加按钮,一旦您单击该按钮并选择了期望的电影,该按钮将被删除并添加到第二页,即 mylist 页面。
在我的列表页面上,会有三部初始电影。每部电影下面都有一个删除按钮,一旦我点击了删除按钮,期望是选定的电影被删除并被添加回主页。
现在,我已经实现了添加按钮,一旦我点击添加按钮,所选电影将被删除并添加到我的列表页面。
单击删除后,问题就出在 mylist 页面中。选定的电影被删除,但没有添加到主页。
Home.js
class Home extends Component {
handleClick = id => {
this.props.addToList(id);
this.props.removeFromRecom(id);
};
render() {
let addedRecom1 = this.props.addedRecom.map(item => {
return (
<div key={item.id} style={{ float: "left", marginLeft: "20px" }}>
<Image webP={item.img}></Image>
<p style={{ marginLeft: "44px" }}>{item.title}</p>
<button
to="/"
onClick={() => this.handleClick(item.id)}
style={{
marginLeft: "53px",
paddingLeft: "10px",
paddingRight: "10px",
paddingTop: "0px",
marginTop: "0px",
marginBottom: "20px"
}}
>
add
</button>
</div>
);
});
return (
<div>
<div>
<NavLink to="/myList" style={{ textDecoration: "none" }}>
<a
style={{
marginLeft: "378px",
fontFamily: "Arial Black",
color: "black",
border: "solid 1px",
backgroundColor: "orange",
paddingLeft: "35px",
paddingRight: "20px"
}}
>
<i
class="fa fa-plus"
style={{ paddingRight: "10px", paddingLeft: "5px" }}
></i>
My list
</a>
</NavLink>
<p style={{ marginTop: "20px", marginLeft: "20px" }}>
Recommendations
</p>
</div>
<div>
{this.props.recommendations.map(item => {
return (
<div key={item.id} style={{ float: "left", marginLeft: "20px" }}>
<Image webP={item.img}></Image>
<p style={{ marginLeft: "44px" }}>{item.title}</p>
<button
to="/"
onClick={() => this.handleClick(item.id)}
style={{
marginLeft: "53px",
paddingLeft: "10px",
paddingRight: "10px",
paddingTop: "0px",
marginTop: "0px",
marginBottom: "20px"
}}
>
add
</button>
</div>
);
})}
</div>
{addedRecom1}
</div>
);
}
}
const mapStateToProps = state => {
return {
addedRecom: state.addedRecom,
recommendations: state.recommendations
};
};
const mapDispatchToProps = dispatch => {
return {
addToList: id => {
dispatch(addToList(id));
},
removeFromRecom: id => {
dispatch(removeFromRecom(id));
}
};
};
export default connect(mapStateToProps, mapDispatchToProps)(Home);
MyList.js
class MyList extends Component {
handleRemoveMovie = id => {
this.props.removeFromList(id);
this.props.addToRecom(id);
};
render() {
let addedMovies = this.props.addedMovies.map(item => {
return (
<div key={item.id} style={{ float: "left", marginLeft: "20px" }}>
<Image webP={item.img}></Image>
<p style={{ marginLeft: "44px" }}>{item.title}</p>
<button
to="myList"
onClick={() => {
this.handleRemoveMovie(item.id);
}}
style={{
marginLeft: "53px",
paddingLeft: "10px",
paddingRight: "10px",
paddingTop: "0px",
marginTop: "0px",
marginBottom: "20px"
}}
>
remove
</button>
</div>
);
});
return (
<div>
<div>
<NavLink to="/" style={{ textDecoration: "none" }}>
<a
style={{
marginLeft: "317px",
fontFamily: "Arial Black",
color: "black",
border: "solid 1px",
backgroundColor: "orange",
paddingLeft: "28px",
paddingRight: "20px"
}}
>
<i
class="fa fa-hand-o-left"
style={{ paddingRight: "10px", paddingLeft: "5px" }}
></i>
back to Home
</a>
</NavLink>
<p style={{ marginTop: "20px", marginLeft: "20px" }}>My Lists</p>
</div>
<div>
{this.props.mylist.map(item => {
return (
<div key={item.id} style={{ float: "left", marginLeft: "20px" }}>
<Image webP={item.img}></Image>
<p style={{ marginLeft: "44px" }}>{item.title}</p>
<button
to="myList"
onClick={() => {
this.handleRemoveMovie(item.id);
}}
style={{
marginLeft: "53px",
paddingLeft: "10px",
paddingRight: "10px",
paddingTop: "0px",
marginTop: "0px",
marginBottom: "20px"
}}
>
remove
</button>
</div>
);
})}
</div>
{addedMovies}
</div>
);
}
}
const mapStateToProps = state => {
return {
addedMovies: state.addedMovies,
mylist: state.mylist
};
};
const mapDispatchToProps = dispatch => {
return {
removeFromList: id => {
dispatch(removeFromList(id));
},
addToRecom: id => {
dispatch(addToRecom(id));
}
};
};
export default connect(mapStateToProps, mapDispatchToProps)(MyList);
reducer.js
const initialState = {
mylist: [
{
title: "Futurama",
id: 1,
img: "http://cdn1.nflximg.net/webp/7621/3787621.webp"
},
{
title: "The Interview",
id: 2,
img: "http://cdn1.nflximg.net/webp/1381/11971381.webp"
},
{
title: "Gilmore Girls",
id: 3,
img: "http://cdn1.nflximg.net/webp/7451/11317451.webp"
}
],
recommendations: [
{
title: "Family Guy",
id: 4,
img: "http://cdn5.nflximg.net/webp/5815/2515815.webp"
},
{
title: "The Croods",
id: 5,
img: "http://cdn3.nflximg.net/webp/2353/3862353.webp"
},
{
title: "Friends",
id: 6,
img: "http://cdn0.nflximg.net/webp/3200/9163200.webp"
}
],
addedMovies: [],
addedRecom: []
};
const reducer = (state = initialState, action) => {
if (action.type === REMOVE_FROM_RECOM) {
let Recom = state.recommendations.filter(item => item.id !== action.id);
return {
...state,
recommendations: Recom
};
}
if (action.type === ADD_TO_LIST) {
let addedMovie = state.recommendations.find(item => item.id === action.id);
let existed_movie = state.mylist;
if (existed_movie) {
return {
...state,
addedMovies: [...state.addedMovies, addedMovie]
};
}
}
if (action.type === ADD_TO_RECOM) {
let add_recom = state.mylist.find(item => item.id === action.id);
let current_recom = state.recommendations;
if (current_recom) {
return {
...state,
addedRecom: [...state.addedRecom, add_recom]
};
}
}
if (action.type === REMOVE_FROM_LIST) {
let removedMovie = state.mylist.find(item => item.id === action.id);
let newMovie = state.addedMovies.filter(item => item.id !== action.id);
return {
...state,
addedMovies: newMovie
};
} else {
return state;
}
};[![enter image description here][1]][1]
export default reducer;
TypeError: Cannot read property 'id' of undefined
(anonymous function)
src/Home.js:17
14 | render() {
15 | let addedRecom1 = this.props.addedRecom.map(item => {
16 | return (
> 17 | <div key={item.id} style={{ float: "left", marginLeft: "20px" }}>
| ^ 18 | <Image webP={item.img}></Image>
19 | <p style={{ marginLeft: "44px" }}>{item.title}</p>
20 | <button
【问题讨论】:
-
让我们更新您的问题。让我们对其进行编辑以清楚地说明问题是什么,您有什么结果以及您期望什么结果。只包括代码的相关部分。这样可以更轻松地了解您的问题并提出解决方案。
-
我怀疑问题出在
let add_recom = state.mylist.find(item => item.id === action.id);如果add_recom未定义,它可能会抛出该错误。 -
我又编辑了,很抱歉造成混乱,希望这次很清楚@Ibu
-
感谢@Neil Chowdhury 的评论 state.mylist 有问题吗?
-
使用 redux devtools 并观察商店,或在出现错误之前运行
console.log(state.mylist)以查看问题所在
标签: javascript reactjs typescript redux reducers