【问题标题】:better way to return states within nested objects in a reducer在reducer的嵌套对象中返回状态的更好方法
【发布时间】:2019-07-23 20:07:45
【问题描述】:

我正在从后端检索数据,数据结构是这样的。

数据结构

{
  "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} 等操作。

我想实现这个reducer示例

https://github.com/hibiken/hackafy/blob/master/src/reducers/posts.js

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

减速器

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;
  }
};

【问题讨论】:

    标签: reactjs redux react-redux


    【解决方案1】:

    您应该按照redux docs 中的说明规范您的状态。 重点:

    1. 您应该让商店尽可能平坦
    2. 尽量减少重复信息=>只设置ids引用而不是实际数据
    3. 不要使用数组来存储您的数据,因为您将不得不经常使用查找或过滤器,而是使用带有键的地图/对象作为实际对象的访问点,如下所示:

      comments: {comment_id1: {title: 'title', author:'author_id'}}

    要获取所有 cmets,请添加一个 allComments 数组,其中只有这样的 ids

    allComments: ['comment_id1']
    

    您应该为每个数据子集使用一个新的 reducer。 如果您有更多问题,请告诉我或阅读文档。

    【讨论】:

    • 是的,如果您的应用程序发展壮大,您会发现更容易让所有内容保持同步并且只有一个事实来源。这将显着降低 reducer 的复杂性,这比仅仅将数据从后端复制到 state 并处理 reducer 本身内的嵌套更新更有价值。
    猜你喜欢
    • 2021-04-30
    • 2017-08-08
    • 1970-01-01
    • 1970-01-01
    • 2018-06-12
    • 2018-06-03
    • 1970-01-01
    • 2017-04-05
    • 2020-05-22
    相关资源
    最近更新 更多