我需要增加和减少每次点击(对于“喜欢”按钮)。我想出了增加相似值的逻辑,但是如何减少该值呢?
计数几乎等于数组的长度,即该特定帖子/图像的点击次数。
因此,这是递增喜欢值的逻辑,并且此方法有效,它将递增到无穷大,这不是我想要的。我在寻找的是减少器逻辑,它将处理减量值,就像POST_LIKE_SUCCESS
一样
console.log( newState.images.find(image => image.id === action.data).likes)
数据结构如下
数据结构。
{
"id": 154,
"image_title": "iiisdd",
"img_url": "https://res*******",
"created_at": "2019-07-18T19:44:49.805Z",
"updated_at": "2019-07-18T19:44:49.805Z",
"user_id": 1,
"user": {
"id": 1,
"googleId": null,
"username": "E*******",
"password": "$***********JwCO",
"email": "e******",
"created_at": "2019-06-23T18:57:17.253Z",
"updated_at": "2019-06-23T18:57:17.253Z"
},
"comments": [
{
"id": 51,
"comment_body": "owls life",
"created_at": "2019-07-18T20:04:51.484Z",
"updated_at": "2019-07-18T20:04:51.484Z",
"user_id": 8,
"image_id": 154,
"user": {
"id": 8,
"googleId": null,
"username": "guest",
"password": "$************",
"email": "***********l.com",
"created_at": "2019-07-18T20:04:34.315Z",
"updated_at": "2019-07-18T20:04:34.315Z"
}
},
{
"id": 52,
"comment_body": "dadad",
"created_at": "2019-07-19T20:16:40.103Z",
"updated_at": "2019-07-19T20:16:40.103Z",
"user_id": 1,
"image_id": 154,
"user": {
"id": 1,
"googleId": null,
"username": "**********",
"password": "$*********O",
"email": "e*******m",
"created_at": "2019-06-23T18:57:17.253Z",
"updated_at": "2019-06-23T18:57:17.253Z"
}
},
{
"id": 53,
"comment_body": "test",
"created_at": "2019-07-21T22:12:44.729Z",
"updated_at": "2019-07-21T22:12:44.729Z",
"user_id": 1,
"image_id": 154,
"user": {
"id": 1,
"googleId": null,
"username": "E******d",
"password": "$********4WjO",
"email": "********",
"created_at": "2019-06-23T18:57:17.253Z",
"updated_at": "2019-06-23T18:57:17.253Z"
}
}
],
"likes": [
{
"id": 24,
"user_id": 2,
"image_id": 154,
"created_at": "2019-07-22T19:26:27.034Z",
"deleted_at": "2019-07-22T19:26:27.034Z",
"restored_at": "2019-07-22T19:26:27.034Z",
"updated_at": "2019-07-22T19:26:27.034Z"
},
{
"id": 77,
"user_id": 1,
"image_id": 154,
"created_at": "2019-07-23T02:55:31.051Z",
"deleted_at": "2019-07-23T02:55:31.051Z",
"restored_at": "2019-07-23T02:55:31.051Z",
"updated_at": "2019-07-23T02:55:31.051Z"
}
]
}
我想要删除类似Redux样板计数器之类的东西。
state - 1
减速器
import {
UPLOAD_IMAGE_SUCCESS,
POST_COMMENT_SUCCESS,
DELETE_IMAGE_FAILURE,
FETCH_IMAGES_SUCCESS,
DISLIKE_POST_SUCCESS,
POST_COMMENT,
POST_LIKE,
POST_LIKE_SUCCESS,
POST_LIKE_FAILURE,
DELETE_IMAGE_SUCCESS,
} from '../actions/types';
const initialState = {
images: [],
likedByuser: false,
};
export default (state = initialState, action) => {
switch (action.type) {
case FETCH_IMAGES_SUCCESS:
return {
...state,
images: action.images,
};
.....
case DELETE_IMAGE_SUCCESS:
// console.log(action)
return {
...state,
images: state.images.filter(img => img.id !== action.data),
};
case DELETE_IMAGE_FAILURE:
return {
...state,
error: action.error,
};
case POST_LIKE_SUCCESS:
console.log(action.data);
const newState = { ...state }; // here I am trying to shallow copy the existing state;
const existingLikesOfPost = newState.images.find(image => image.id === action.data).likes;
console.log(existingLikesOfPost)
newState.images.find(image => image.id === action.data).likes = [...existingLikesOfPost, action.newLikeObject]; // using this approach I got some code duplication so I suggested the first approach of using **push** method of array.
// console.log(newState)
return newState;
case DISLIKE_POST_SUCCESS:
console.log(action.data)
// working on logic that will decrement
return{
...state - 1
}
default:
return state;
}
};
console.log(action.data)
{
"type": "POST_LIKE",
"data": {
"id": 154,
}
}
表达后端逻辑
router.post('/like/:id', (req, res) => {
const { id } = req.params;
if (id !== null || 'undefined') {
Image.forge({ id })
.fetch({ withRelated: ['user', 'comments', 'likes'] })
.then((likes) => {
const like = likes.toJSON();
// console.log(like.likes);
const existingUserlikes = like.likes.map(user => user.user_id);
// checking to see if a user already liked his own post
// if existing user does not have user id, user can like post,
// else if user already like this post wont be able to.
const newLike = new Likes({
image_id: id,
user_id: req.user.id
});
if (existingUserlikes.includes(req.user.id)) {
// !newLike do not create a new row of likes if like from this user already exists
if (!newLike) {
Likes.forge().where({ user_id: req.user.id, image_id: id }).destroy();
}
return Likes.forge().where({user_id: req.user.id, image_id: id }).fetch()
.then((like) => like.destroy()
.then( () => res.json({ error: true, data: { message: 'like deleted' } })));
}
newLike.save().then(like => res.status(200).json({ status: 'You liked this post', like: newLike }));
});
}
});
答案 0 :(得分:1)
我觉得您正在使事情复杂化。就个人而言,我不会像这样构造我的数据。应避免深层嵌套的对象。您可以改为具有多个相互链接的对象。另外,我会将帖子ID作为对象键,因此当我要更新特定帖子时,我只需要
return {
...state,
[action.id]: {
...state[action.id],
...action.newData,
}
}
在您的情况下,我将过滤掉不喜欢该帖子的用户ID:
...
case DISLIKE_POST_SUCCESS:
const newState = { ...state };
const predicate = ({ id }) => id === action.data;
const existingLikes = newState.images.find(predicate).likes;
// You would have to pass userId as an action payload as I'm assuming you are deleting
// the likes based on the userId.
const newLikes = existingLikes.filter(({ user_id }) => user_id !== action.userId);
newState.images.find(predicate).likes = newLikes;
答案 1 :(得分:0)
最简单的方法是使用immutability-helper。这使您可以更新不可变的对象,而不必担心整个对象。 您可以这样更新它:
return update(state, {
likes: {$remove: [action.id]}
});
如果以后再更改喜欢的对象,则不必更改代码的这一部分,因为它只会更新所提到的数据。