翻译:疯狂的技术宅
做者:Nick Sweeting
英文标题:Shape your redux store like your database
英文原文:https://hackernoon.com/shape-...
说明:本专栏文章首发于公众号:jingchengyideng 。javascript
使用索引能够从多个维度表现数据。(此处应为动图,请看原文)html
最近我在RC聊天系统浏览关于 JavaScript 的一些讨论时,注意到了Kate Ray的一个问题:前端
应该怎样在 redux 存储中结构话个人数据?java
的确,这是使用 redux 时最多见的问题之一。react
有不少须要考虑的东西,你常常会像访问一个行列表同样遍历数据吗? 你须要以O(1)的时间复杂度快速访问某些条目吗?git
我在实践中获得了一些经验,一般在访问时间和迭代的难易程度之间作一些权衡。github
若是你须要存储一些每一个项目都带有id的数据,可使用Array
, Object
, 或者 对象数组来保存。数据库
[{values}]
:这是最多见的一种范式。它使迭代变得容易,可是不通过迭代和过滤就不能快速访问特定条目。redux
categories: [ {name: 'abs', id: '32o8wafe', exercises: ['crunches', 'plank']}, {name: 'arms', id: 'oaiwefjo', exercises: [...]}, {name: 'legs', id: 'aoijwfeo', exercises: [...]}, ]
id
为索引的对象{id: {values}}
:这种方法能够是你以O(1)的时间复杂度快速访问每一个项目,可是在使用object.values()
进行迭代时,不能很容易地访问给定项目对应的id
。后端
[{id: {values}}]
:这让你能够遍历列表并轻松访问id
和值,可是它作到以O(1)的时间复杂度快速访问,由于它是一个数组。
categories: [ {32o8wafe: {name: 'abs', exercises: [...]}, {oaiwefjo: {name: 'arms', exercises: [...]}, {3oij2e3c: {name: 'legs', exercises: [...]}, ]
在学习redux的过程当中,我在Monadical偶然发现了一种不一样的方法,它使咱们受益于简单的Object.values(state.categories)
,并可以以O(1)的时间复杂度快速对单个项目的访问:
categories: { 32o8wafe: {id: '32o8wafe', name: 'abs', exercises: [...]}, oaiwefjo: {id: 'oaiwefjo', name: 'arms', exercises: [...] }, 3oij2e3c: {id: '3oij2e3c', name: 'legs', exercises: [...] }, }
请注意id
既是行的键,同时也是行自己的属性。这一点点重复使咱们在访问时间上有了很大的灵活性。这也与Redux文档推荐的归一化(也称扁平)模型兼容。
如今你能够遍历数据了,也能够在迭代时访问id
!
Object.values(categories).map(cat => ({id: cat.id, name: cat.name}))
或者经过id
快度访问任何项目!
categories[category_id].name
咱们将这样组织好的数据发送到前端,前端就不须要作任何处理来生成id: values
映射,从而也就减小了错误的产生。在后端很容易作到这一点,由于你极可能从数据库中提取数据,而数据库中已经存在id
字段,能够直接将其做为键使用。
请注意,咱们上面介绍的结构只是一些行的索引,索引是id
。你也能够这样设计本身的存储结构:使用你想要用的字段生成索引,来达到O(1)的时间复杂度进行快速访问
categories_by_name = { abs: '32o8wafe', arms: 'oaiwefjo', legs: '3oij2e3c', } const get_category_by_name = (store, name) => store.getState().categories[categories_by_name[name]]
也能够为一样的数据构建尽量多的索引,这样将使你在任何列上基于O(1)的速度进行访问,就像在数据库中同样。
把你存储的数据想象成为图书馆,能够用索引快速找到任何项目(此处应为动图,请看原文)
这里描述的模式正是Normalizr库所使用的模式。若是你想把你的数据扁平化(按类型分开),就像我前面介绍的索引概念同样,请阅读Normalizr的文档《Redux Without Profanity docs》。
Redux 和 Normalizr 与 Reselect 配合的也很好,若是你关心性能,而且喜欢有一个中央列表的记忆选择器,能够关注一下。
欢迎扫描二维码关注公众号,天天推送我翻译的技术文章。