如何在React / Redux应用程序中指定状态的形状?

edd*_*ddy 5 state-management reactjs redux

自从我开始阅读SPA以来,最困扰我的是如何处理应用程序状态。

尽管我在Redux中找到了我一直在寻找的大多数答案,但仍有一些我不确定如何处理的事情。

其中之一是如何指定我要在我的应用程序中使用的“实体”的形状。在过去使用的其他框架中,为此目的我已经看到了ES2015类的广泛使用,但是到目前为止,在React / Redux应用程序中,对象常量是表达应用程序状态的首选方式。昨晚,我在阅读有关在redux文档中规范化数据的内容,尽管它为我提供了有关如何处理深层嵌套对象的好主意,但让我感到缺少某些东西,并且需要在一个单独的地方指定它找到并尽可能清楚地知道应用程序状态的结构/形状。

取得上述文章中使用的样本数据:

{
    posts : {
        byId : {
            "post1" : {
                id : "post1",
                author : "user1",
                body : "......",
                comments : ["comment1", "comment2"]    
            },
            "post2" : {
                id : "post2",
                author : "user2",
                body : "......",
                comments : ["comment3", "comment4", "comment5"]    
            }
        }
        allIds : ["post1", "post2"]
    },
    comments : {
        byId : {
            "comment1" : {
                id : "comment1",
                author : "user2",
                comment : ".....",
            },
            "comment2" : {
                id : "comment2",
                author : "user3",
                comment : ".....",
            },
            "comment3" : {
                id : "comment3",
                author : "user3",
                comment : ".....",
            },
            "comment4" : {
                id : "comment4",
                author : "user1",
                comment : ".....",
            },
            "comment5" : {
                id : "comment5",
                author : "user3",
                comment : ".....",
            },
        },
        allIds : ["comment1", "comment2", "comment3", "commment4", "comment5"]
    },
    users : {
        byId : {
            "user1" : {
                username : "user1",
                name : "User 1",
            }
            "user2" : {
                username : "user2",
                name : "User 2",
            }
            "user3" : {
                username : "user3",
                name : "User 3",
            }
        },
        allIds : ["user1", "user2", "user3"]
    }
}
Run Code Online (Sandbox Code Playgroud)

您将如何表达这些数据的形状?像这样?

{
    posts : {

    },
    comments : {

    },
    users : {

    }
}
Run Code Online (Sandbox Code Playgroud)

也许:

{
    posts : {
        byId : {

        }
        allIds : []
    },
    comments : {
        byId : {

        }
        allIds : []
    },
    users : {
       byId : {

        }
        allIds : []
    }
}
Run Code Online (Sandbox Code Playgroud)

好吧,这告诉我关于每个对象内部对象的实际形状的任何信息,byId而这正是我开始研究Redux以来一直困扰着我的东西。

因此,问题是,是否有任何方法/通用做法可以让我以最清晰的方式表示形状,尤其是构成商店将要管理的状态的对象的每个属性?

Ema*_*ico 0

Redux 的好处是你可以非常清晰地分离状态的关注点。每个减速器都负责自己的状态部分,如果您最终通过添加更多数据/逻辑来扩展减速器,则只需将该减速器分解为更小的减速器即可。

一般来说,我会避免在减速器内的大数据集合中使用数组。数组很酷,并为您提供了许多不错的功能(排序、过滤、归约等),但循环遍历它们的成本很高。如果可以的话,使用对象并使用ID来标识您的对象,这样您就可以以最快的方式访问该对象。

使用您的示例,我将使用第一种方法:

{
  posts: {
    1554: {},
    1557: {}
  },
  comments: {},
  users: {},
}
Run Code Online (Sandbox Code Playgroud)

如果您需要跟踪数组中的列表对象您只需在posts减速器中创建两个新的减速器:

// postsReducer.js
import byId from 'postsByIdReducer'
import allIds from 'allIdsReducer'

export default combineReducers({
  byId,
  allIds
})
Run Code Online (Sandbox Code Playgroud)

所以你的状态会像

{
  posts: {
    byIds: {},
    allIds: []
  }
}
Run Code Online (Sandbox Code Playgroud)