为什么我的 Redux 存储应该是可序列化的?

IT技术 javascript reactjs redux flux
2021-03-31 06:03:47

在阅读 redux 文档时,我发现了这一点:

不过,您应该尽最大努力保持状态可序列化。不要在里面放任何你不能轻易变成 JSON 的东西。

所以我的问题是,保持状态可序列化有什么好处?或者,如果我将不可序列化的数据放入存储中,我可能会遇到什么困难?

而且我相信这不是 redux 独有的——Flux,甚至 React 本地状态也暗示了同样的事情。


为了让我清楚这里是一个例子。假设商店结构是这样的。

{
    books: { 
        1: { id: 1, name: "Book 1", author_id: 4 }
    },
    authors: {
        4: { id: 4, name: "Author 4" }
    }
}

这应该看起来不错。但是,当我尝试访问“第一本书的作者”时,我必须编写如下代码:

let book = store.getState().books[book_id];
let author = store.getState().authors[book.author_id];

现在,我要定义一个类:

class Book {
    getAuthor() {
        return store.getState().authors[this.author_id];
    }
}

我的商店将是:

{
    books: {
        1: Book(id=1, name="Book 1")
    },
    ...
}

这样我就可以通过使用以下方法轻松获得作者:

let author = store.getState().books[book_id].getAuthor();

第二种方法可以让“书”对象知道如何检索作者数据,因此调用者不需要知道书和作者之间的关系。那么,为什么我们不使用它,而不是像方法 1 一样将“普通对象”保存在商店中?

任何想法表示赞赏。

4个回答

直接来自redux 常见问题解答

我可以在我的商店状态中放置函数、Promise或其他不可序列化的项目吗?

强烈建议您只将普通的可序列化对象、数组和原语放入您的商店。从技术上讲,将不可序列化的项目插入存储中是可行的,但这样做会破坏存储内容的持久化和再水化能力,并干扰时间旅行调试。

如果您对持久性和时间旅行调试等可能无法按预期工作的事情感到满意,那么完全欢迎您将不可序列化的项目放入您的 Redux 存储中。归根结底,这是您的应用程序,您如何实现它取决于您。与 Redux 的许多其他事情一样,请确保您了解所涉及的权衡。


进一步阅读:

@markerikson 你和他们一起做得很好,尤其是问题链接和第三方资源的集合真的很有帮助!
2021-05-28 06:03:47
作为 Redux FAQ 的作者,这正是我写它的原因:) 很高兴看到人们引用它并使用它来帮助回答问题!
2021-06-10 06:03:47
感谢您的回答,尤其是提到时间旅行。这对我来说是新的,保持商店可序列化是有意义的。
2021-06-16 06:03:47

补充一下@Timo 所说的,如果您想在状态树中设置 2 个状态之间的关系并使用计算值,reselect则最适合该场景。它允许创建selectors可用于定义计算状态。在您的情况下,author可以使用book. https://github.com/reactjs/reselect

@timo 的回答是正确的。此外,我推荐一个名为Redux-ORM的库来处理 Redux 存储中的规范化/关系数据。有关更多信息的链接,请参阅我最近在 React + Redux SPA SaaS处理大型存储中的数据一致性的评论

添加此内容是因为您要求提供建议。如果你只想从你的类中创建一个对象,那么你可以简单地创建一个返回一个对象的函数。在您的 Book 类中,它可能类似于

function newBookObject({id, name}) {
    return {id, name}
}

你的商店看起来像

{
    books: {
        1: newBookObject({id: 1, name: "Book 1"})
    },
    ...
}

返回的对象不能包含任何函数,它应该只是一个纯数据的普通静态对象,没有别的。你不能序列化不是纯数据的东西。