如何减少化简器中嵌套数组中的计数值

时间:2019-07-23 14:33:52

标签: reactjs redux react-redux

我需要增加和减少每次点击(对于“喜欢”按钮)。我想出了增加相似值的逻辑,但是如何减少该值呢?

计数几乎等于数组的长度,即该特定帖子/图像的点击次数。

因此,这是递增喜欢值的逻辑,并且此方法有效,它将递增到无穷大,这不是我想要的。我在寻找的是减少器逻辑,它将处理减量值,就像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 }));
      });
  }
});

2 个答案:

答案 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]} });

如果以后再更改喜欢的对象,则不必更改代码的这一部分,因为它只会更新所提到的数据。