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

Zho*_*hao 8 normalization reactjs 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"]
    }
}
Run Code Online (Sandbox Code Playgroud)

gpm*_*dam 0

您可以通过多种方式来看待这个问题:

  1. 每个元素的减速器负责清理删除用户的任何操作的数据,或者;
  2. 删除用户的操作会产生删除多个关联项目(或调度多个关联操作)的副作用

选项1

假设您有如下操作:

  const deleteUser = userId => {
    return ({
      type: 'DELETE_USER',
      userId
    })
  }
Run Code Online (Sandbox Code Playgroud)

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

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

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

  }
Run Code Online (Sandbox Code Playgroud)

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

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

选项2

如果您不喜欢上述内容,并且希望保持一定程度的关注点分离,那么请考虑寻找一种方法来触发与操作相关的副作用,例如redux-sagaredux-thunk

实现会根据库的不同而有所不同,但其想法是:

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