Reactjs 在减速器中的嵌套对象内返回状态的更好方法

Reactjs 在减速器中的嵌套对象内返回状态的更好方法,reactjs,redux,react-redux,Reactjs,Redux,React Redux,我从后端检索数据,数据结构如下 数据结构 { "id": 154, "image_title": "iiisdd", "img_url": "*********", "created_at": "2019-07-18T19:44:49.805Z", "updated_at": "2019-07-18T19:44:49.805Z", "user_id": 1, "user": { "id": 1, "googleId": null, "usern

我从后端检索数据,数据结构如下

数据结构

{
  "id": 154,
  "image_title": "iiisdd",
  "img_url": "*********",
  "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": "*******,
    "password": "$********",
    "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": "********u",
        "email": "*******m",
        "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": "*********",
        "email": "el***********",
        "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": "********",
        "password": "*********",
        "email": "el********",
        "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": 141,
      "user_id": 1,
      "image_id": 154,
      "created_at": "2019-07-23T19:57:08.178Z",
      "deleted_at": "2019-07-23T19:57:08.178Z",
      "restored_at": "2019-07-23T19:57:08.178Z",
      "updated_at": "2019-07-23T19:57:08.178Z"
    }
  ]
}
我认为我在reducer中传递数据的效率不高。重构代码的更好方法是什么,这样我就可以轻松地将数据映射到组件/ui上

无需执行
{this.props.image.images.comments}
{this.props.images.likes}
等操作

我想实现这个示例

但我不确定我是否真的也需要

减速器

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 UPLOAD_IMAGE_SUCCESS:
      const newImage = action.data;
      return {
        images: [
          {
            id: newImage[0].id,
            user: {
              username: newImage[0].user.username,
            },
            comments: {
              comment_body: newImage[0].comments.comment_body,
            },
            image_title: newImage[0].image_title,
            img_url: newImage[0].img_url,
          },
          ...state.images, // pass the previous 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:
      console.log(action);
      return {
        ...state,
      };
    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.
      return newState;
    case DISLIKE_POST_SUCCESS:
      // ....
    case POST_COMMENT:
      return {
        ...state,
      };
    case POST_COMMENT_SUCCESS:
      //  adds a comment to a post without having to re render.
      // console.log(action.data.commentBody);
      return {
        ...state,
        images: state.images.map((image) => {
          // appends new comment withing images redux state. only if image.id === action.id
          if (image.id === action.id) {
            return {
              ...image,
              comments: [
                ...image.comments,
                {
                  comment_body: action.data[0].comment_body,
                  user: {
                    username: action.data[0].user.username,
                  },
                },
              ],
            };
          }
          return image;
        }),
      };
    default:
      return state;
  }
};

您应该按照中的说明使您的状态正常化。 要点:

  • 你应该尽量使你的商店保持平坦
  • 尝试减少重复信息=>仅设置ID引用而不是实际数据
  • 不要使用数组存储数据,因为您将不得不大量使用“查找”或“筛选”,而是使用带有键的映射/对象作为实际对象的访问点,如下所示:

    comments:{comment_id 1:{title:'title',author:'author_id'}}

  • 要获取所有注释,请添加一个allComments数组,其中仅包含如下ID

    allComments: ['comment_id1']
    
    您应该为这些数据子集中的每一个使用新的缩减器。
    如果您有更多问题,请告诉我或阅读文档。

    类似于此设置,对吗?是的,如果您的应用程序不断增长,您将发现更容易保持所有内容的同步,并且只有一个真实来源。这将大大降低reducer的复杂性,这比将数据从后端复制到状态并处理reducer本身中的嵌套更新更有价值。