如何在我的减速器中更新特定的嵌套项目?

时间:2020-08-11 23:16:28

标签: javascript reactjs redux

我的减速器具有以下结构:

{
    "id": 8,
    "location_name": "Some place",
    "lat": "nn.nnnnnn",
    "lng": "-nn.nnnnn",
    "review_count": 3,
    "score_avg": 3.00,
    "reviews": [
        {
            "id": 14,
            "userId": 1,
            "userName": "JohnDoe",
            "body": "Lorem Ipsum.",
            "score": null,
            "likes": 2,
            "liked": true,
            "review_pic": null
        },
        {
            "id": 15,
            "userId": 1,
            "userName": "JohnDoe",
            "body": "Lorem Ipsum.",
            "score": null,
            "likes": 0,
            "liked": false,
            "review_pic": null
        },
        {
            "id": 13,
            "userId": 4,
            "userName": "JohnDoe",
            "body": "Lorem Ipsum.",
            "score": null,
            "likes": 0,
            "liked": false,
            "review_pic": null
        }
    ]
}

另一方面,我有一个返回ID的动作创建者。我正在尝试获取此ID,以将Likes更改为true并设置likes + 1,但是该reducer状态的嵌套性质使我感到震惊。

编辑:这是我一直在尝试使用我的减速器的运气:

import {GET_REVIEWS, CLEAR_REVIEWS, LIKE} from './reviewTypes';

const initialState = [];

const reviewReducer = (state = initialState, action) => {
    switch(action.type) {
        case GET_REVIEWS:
            return action.payload;
        case LIKE:
           const reviews = state.reviews.map(review => {
               if(review.id === action.payload) {
                   return {
                       ...review,
                       liked: true,
                       likes: review.likes++
                   }
               } else {
                   return review;
               }
           });
           return {
               ...state,
               reviews
           }
        case CLEAR_REVIEWS:
            return [];
        default:
            return state;
    }
}

export default reviewReducer;

3 个答案:

答案 0 :(得分:0)

我使用Array#some遍历array.reviews以查找具有所需ID的评论。如果找到的话,我会增加点赞并将喜欢设置为true,

function updateLike(id, array) {
    array.reviews.some(review => {
        if (review.id==id) {
            review.likes++;
            review.liked = true;
            return true;
        }
    });
}


let array = {
    "id": 8,
    "location_name": "Some place",
    "lat": "nn.nnnnnn",
    "lng": "-nn.nnnnn",
    "review_count": 3,
    "score_avg": 3.00,
    "reviews": [
        {
            "id": 14,
            "userId": 1,
            "userName": "JohnDoe",
            "body": "Lorem Ipsum.",
            "score": null,
            "likes": 2,
            "liked": true,
            "review_pic": null
        },
        {
            "id": 15,
            "userId": 1,
            "userName": "JohnDoe",
            "body": "Lorem Ipsum.",
            "score": null,
            "likes": 0,
            "liked": false,
            "review_pic": null
        },
        {
            "id": 13,
            "userId": 4,
            "userName": "JohnDoe",
            "body": "Lorem Ipsum.",
            "score": null,
            "likes": 0,
            "liked": false,
            "review_pic": null
        }
    ]
};

updateLike(15, array);
console.log(array);

答案 1 :(得分:0)

您可以使用https://artsy.github.io/blog/2018/11/21/conditional-types-in-typescript/来获取具有特定id的元素。

const data = { "id": 8, "location_name": "Some place", "lat": "nn.nnnnnn", "lng": "-nn.nnnnn", "review_count": 3, "score_avg": 3.00, "reviews": [ { "id": 14, "userId": 1, "userName": "JohnDoe", "body": "Lorem Ipsum.", "score": null, "likes": 2, "liked": true, "review_pic": null }, { "id": 15, "userId": 1, "userName": "JohnDoe", "body": "Lorem Ipsum.", "score": null, "likes": 0, "liked": false, "review_pic": null }, { "id": 13, "userId": 4, "userName": "JohnDoe", "body": "Lorem Ipsum.", "score": null, "likes": 0, "liked": false, "review_pic": null } ] };
let id = 13;
let obj = data.reviews.find(x => x.id === id);
if(obj) obj.liked = true;
console.log(data);

答案 2 :(得分:0)

您不必在那一个上使用reducer,因为您只有一个数组,并且useState应该很好,所以这段代码应该对您有用。

const onItemLike = (itemID) => {
          setState(state.map(x => {
               if(reviews.id === itemID)
               return {...x, liked: true, likes: state.reviews[x].likes+1}
          }))
     }