在 Redux 中删除规范化状态的相关实体的最佳实践

Best practice for deleting related entities in normalized state in Redux

从规范化数据中删除一个实体时,我们如何处理删除该实体所拥有的其他实体?例如,对于以下规范化数据,如果我要删除 user1,我还想删除 user1 发表的所有帖子和评论。对于这种情况,是否有任何已知的操作方法或最佳做法?

{
    posts : {
        byId : {
            "post1" : {
                id : "post1",
                author : "user1",
                body : "......",
                comments : ["comment1", "comment2"]    
            }
        },
        allIds : ["post1"]
    },
    comments : {
        byId : {
            "comment1" : {
                id : "comment1",
                author : "user1",
                comment : ".....",
            },
            "comment2" : {
                id : "comment2",
                author : "user1",
                comment : ".....",
            },
        },
        allIds : ["comment1", "comment2"]
    },
    users : {
        byId : {
            "user1" : {
                username : "user1",
                name : "User 1",
            }
        },
        allIds : ["user1"]
    }
}

您可以通过多种方式查看此内容:

  1. 每个元素的缩减程序负责清理删除用户的任何操作的数据,或者;
  2. 删除用户的操作具有删除多个关联项的副作用(或调度多个关联操作)

选项 1

假设您有如下操作:

  const deleteUser = userId => {
    return ({
      type: 'DELETE_USER',
      userId
    })
  }

user 的减速器可能如下所示:

  const users = (state = {}, action) => {

    switch (action.type) {
      case 'DELETE_USER':
        // delete user logic
        break;
    }

  }

好吧,从技术上讲,Redux 中没有任何东西可以阻止您对 postscomments 减速器中的 DELETE_USER 操作做出反应:

  const posts = (state = {}, action) => {
    const newState = Object.assign({}, state);
    switch (action.type) {
      case 'DELETE_USER':
        // delete posts for action.userId
        break;
    }
  }

选项 2

如果您不喜欢上述内容,并希望保持某种程度的关注点分离,那么请考虑寻找一种方法来触发 side-effects 与某个操作相关联,例如 redux-saga or redux-thunk

实现会因库而异,但思路是:

  1. 监听 DELETE_USER 动作
  2. 触发一些动作来:
    1. 删除一个用户(DELETE_USER)
    2. 删除用户的帖子(DELETE_USER_POSTS
    3. 删除用户评论(DELETE_USER_COMMENTS)