[英]Component does not re-render when State is updated using react, redux and immer
I have a simple code which containing a PostFeed component to show feeds and PostItem component inside it which shows each feed.我有一个简单的代码,其中包含一个用于显示提要的 PostFeed 组件和其中显示每个提要的 PostItem 组件。 in PostItem user can do like feed and here a service call and a number of likes will change.在 PostItem 中,用户可以做点赞订阅,这里的服务调用和点赞数会发生变化。 if the current user has liked the feed, the thumb will have a blue color.如果当前用户喜欢该提要,则拇指将显示为蓝色。
everything works fine when the page refreshed, but when the feed gets to like or dislike, the state gets update and a number of likes changed truly but the component color does not change.当页面刷新时一切正常,但是当提要变得喜欢或不喜欢时,状态会更新并且许多喜欢确实改变了,但组件颜色不会改变。 In order to prevent Immutableily, I have used Immer .为了防止一成不变,我使用了Immer 。
Here is the code这是代码
//PostFeed Component
class PostFeed extends Component {
render() {
const { posts } = this.props;
return posts && posts.map(post => <PostItem key={post._id} post={post} />);
}
}
//PostItem Component
class PostItem extends Component {
componentWillReceiveProps(nextProps) {
if (nextProps.post) {
this.setState({ post: nextProps.post });
}
}
onLikeClick(id) {
this.props.addLike(id);
}
isCurrentUserLike(likes: ILike[]) {
const { auth } = this.props;
if (likes.filter(like => like.user === (auth.user as any).id).length > 0) {
return <i className="fas fa-thumbs-up text-info" />;
} else {
return <i className="fas fa-thumbs-up" />;
}
}
render() {
const { post, auth } = this.props;
return (
<div className="card card-body mb-3">
...
<button onClick={this.onLikeClick.bind(this, post._id)} type="button" className="btn btn-light mr-1">
// This line does not re-render
{this.isCurrentUserLike(post.likes)}
<span className="badge badge-light">{post.likes.length}</span>
</button>
}
}
const mapStateToProps = (state) => ({
auth: state.auth
});
export default connect(mapStateToProps, { addLike})(
PostItem
);
this is acition:这是行动:
export const addLike = (id) => (dispatch) => {
axios
.post(`/api/posts/like/${id}`)
.then(res =>
dispatch({
type: "POST_LIKED",
payload: res.data
})
)
.catch(err =>
dispatch({
type: "GET_ERRORS",
payload: err.response.data
})
);
};
and this is reducer:这是减速器:
export default (state = initialState, action) => {
return produce(state, (draft): any => {
switch (action.type) {
case "POST_LIKED":
draft.posts = substitudePost(draft.posts, action.payload);
draft.loading = false;
break;
}}
)}
const substitudePost = (posts, post) => {
const index = posts.findIndex(i => i._id == post._id);
if (index > -1) posts[index] = post;
return posts;
}
and these are Data types:这些是数据类型:
interface initialFeedState= {
posts: IPost[],
post: IPost,
loading: false
};
interface IPost {
_id: string;
user: IUser;
likes: ILike[];
comments: IComment[];
date: string;
}
I think the problem is on this line我认为问题出在这条线上
if (likes.filter(like => like.user === (auth.user as any).id).length > 0) {
You are comparing the user object with authenticated user id , they will never be the same.您正在将用户对象与经过身份验证的用户id进行比较,它们永远不会相同。 And you can use the some function like this你可以使用像这样的一些功能
if (likes.some(like => like.user.id === auth.user.id)) {
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.