如何在RTK(Redux Toolkit)中使用immutable.js?

huangapple go评论65阅读模式
英文:

How to use immutable.js with RTK (redux toolkit)?

问题

我正在将传统的Redux代码迁移到RTK。

在我的传统代码库中,我使用Immutable.js(用于不可变性目的),但对于我将要编写的新代码,我不再需要它,但我希望传统代码在不触碰它的情况下继续工作,并同时使用RTK的configureStore。但我的应用程序报错了:
> 断言失败:在分派之间检测到状态突变,在路径'app._values._tail.array.0._values._root.array.0.array.16._defaultValues.gcm.__hash'中。这可能会导致不正确的行为。(https://redux.js.org/style-guide/style-guide#do-not-mutate-state)

我明白了,这是因为我改变了对象实例,我可以通过以下方式禁用错误:

immutableCheck: false,
serializableCheck: false,

但在我看来,这禁用了太多东西,我希望保留这些设置,但让Immutable.js绕过不可变性检查。
我找到了这段过时的代码,看起来像是我要实现的东西:

// 增强中间件以考虑Immutable.JS可迭代对象的可序列化性
const isSerializable = (value) =>
  Iterable.isIterable(value) || isPlain(value)
const getEntries = (value) =>
  Iterable.isIterable(value) ? value.entries() : Object.entries(value)
const serializableMiddleware = createSerializableStateInvariantMiddleware({
  isSerializable: () => true // 所有值都将被接受
  isSerializable,
  getEntries,
})
const store = configureStore({
  reducer,
  middleware: [serializableMiddleware]
})

在这里:https://github.com/reduxjs/redux-toolkit/pull/141/files 但它不起作用,Iterable现在是Collection,没有isIterable函数,我尝试了isImmutable,但也不起作用。

现在该文件看起来像这样:https://github.com/reduxjs/redux-toolkit/blob/master/docs/api/otherExports.mdx,没有Immutable.js的迹象。

我该怎么办?

跨帖:https://github.com/reduxjs/redux-toolkit/discussions/3539

英文:

I'm migrating legacy Redux code to RTK.

With my legacy code base I was using Immutable.js (for immutability purposes), I don't need it anymore for the new code I'm gonna write, but I would like for the legacy code to keep working without touching it, and while using configureStore from RTK. But my apps throws :
>Invariant failed: A state mutation was detected between dispatches, in the path 'app._values._tail.array.0._values._root.array.0.array.16._defaultValues.gcm.__hash'. This may cause incorrect behavior. (https://redux.js.org/style-guide/style-guide#do-not-mutate-state)

I get it, it's because I change the object instance, I can disable the error doing so :

immutableCheck: false,
serializableCheck: false,

but IMO it disables too much, I would like to keep these settings on, but for Immutable.js to bypass the immutability check.
I found this piece of outdated code that looks like what I'm trying to achieve

// Augment middleware to consider Immutable.JS iterables serializable
const isSerializable = (value) =>
  Iterable.isIterable(value) || isPlain(value)
const getEntries = (value) =>
  Iterable.isIterable(value) ? value.entries() : Object.entries(value)
const serializableMiddleware = createSerializableStateInvariantMiddleware({
  isSerializable: () => true // all values will be accepted
  isSerializable,
  getEntries,
})
const store = configureStore({
  reducer,
  middleware: [serializableMiddleware]
})

here https://github.com/reduxjs/redux-toolkit/pull/141/files but it's not working, Iterable is now Collection and has no isIterable function, I've tried isImmutable but it's not working either.

Now the file looks like this : https://github.com/reduxjs/redux-toolkit/blob/master/docs/api/otherExports.mdx, there's no trace of Immutable.js.

What can I do ?

cross-post: https://github.com/reduxjs/redux-toolkit/discussions/3539

答案1

得分: 0

@EskiMojo14是RTK的维护者之一,他能够为我找到一个解决方案:

"serializableCheck"和"immutableCheck"是两个独立的检查,我们希望您使用getDefaultMiddleware来自定义它们。

例如,下面这段(未经测试的)代码可能会起作用:

import { configureStore, isImmutableDefault, isPlain } from "@reduxjs/toolkit";
import { isImmutable } from "immutable";

const store = configureStore({
  reducer,
  middleware: (getDefaultMiddleware) =>
    getDefaultMiddleware({
      immutableCheck: {
        isImmutable: (value) => isImmutable(value) || isImmutableDefault(value),
      },
      serializableCheck: {
        isSerializable: (value) => isImmutable(value) || isPlain(value),
        getEntries: (value) =>
          isImmutable(value) ? value.entries() : Object.entries(value),
      },
    }),
});
英文:

@EskiMojo14, one of the maintainers on RTK was able to find a solution for me :

> the serializableCheck and immutableCheck are two separate checks, and we want you to customise them using getDefaultMiddleware.
>
> For example, something like the below (untested) code might work:
>
> ts
> import { configureStore, isImmutableDefault, isPlain } from "@reduxjs/toolkit";
> import { isImmutable } from "immutable";
>
> const store = configureStore({
> reducer,
> middleware: (getDefaultMiddleware) =>
> getDefaultMiddleware({
> immutableCheck: {
> isImmutable: (value) => isImmutable(value) || isImmutableDefault(value),
> },
> serializableCheck: {
> isSerializable: (value) => isImmutable(value) || isPlain(value),
> getEntries: (value) =>
> isImmutable(value) ? value.entries() : Object.entries(value),
> },
> }),
> });
>

huangapple
  • 本文由 发表于 2023年6月19日 20:40:26
  • 转载请务必保留本文链接:https://go.coder-hub.com/76506718.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定