2

我正在研究 React with Redux 以重写我们的产品。使用 Redux-Toolkit https://redux-toolkit.js.org/清除了 Redux 周围的许多迷雾。然后发现 React-Router 让状态管理变得乱七八糟,在 redux-first-router https://github.com/faceyspacey/redux-first-router中找到了解决方案。

现在我想结合这些优秀的库。但我认为我在配置中做错了什么。这是代码。从https://codesandbox.io/s/m76zjj924j的沙盒示例开始,我将 configureStore.js 文件更改为(为简单起见,我省略了用户减速器的代码)

import { connectRoutes } from 'redux-first-router';
import { configureStore, getDefaultMiddleware } from '@reduxjs/toolkit'
import { routePaths } from '../routes';

const { reducer: location } = connectRoutes(routePaths);

const {
    middleware: routerMiddleware,
    enhancer: routerEnhancer,
    initialDispatch
  } = connectRoutes(routePaths, { initialDispatch: false });

export default function configureRouteStore() {
  const store = configureStore({
    reducer: {

      location: location
    },
    middleware: [...getDefaultMiddleware(), routerMiddleware],
    enhancers: (defaultEnhancers) => [routerEnhancer, ...defaultEnhancers]
  })
  initialDispatch();
  return store;
}

但是现在每次更新 route = Redux store 时,我都会在浏览器中得到一个异常:

index.js:1 A non-serializable value was detected in the state, in the path: `location.routesMap.PROFILE.thunk`. Value: dispatch => {
  dispatch(USER_DATA_LOADED({
    avatar: null
  }));
  const avatar = `https://api.adorable.io/avatars/${Math.random()}`;
  setTimeout(() => {
    // fake async call
    dispatch(USER_… 
Take a look at the reducer(s) handling this action type: HOME.

PROFILE: { path: "/profile/:username", thunk: fetchUserData }如果路由具有定义为这样的“thunk”属性,我可以看到这源于路由定义:

如果我将 thunk 属性更改为可序列化的值(或删除它),错误就消失了。现在不知何故,thunk 被添加到操作的有效负载中以更新路径。什么...?

该怎么办?好的,我可以让它与传统的 Redux 设置一起使用,但由于我是 redux 工具包的忠实粉丝,它对我来说会很不错,也许还有更多人可以让它与工具箱一起使用。

4

1 回答 1

5

我是 Redux 维护者和 Redux Toolkit 的创建者。

根据该错误消息并阅读 Redux-First-Router 源代码,该库似乎确实在尝试将 thunk 函数存储在 Redux store中。这是一个问题,因为我们特别指示用户不要将不可序列化的值(如函数)放入 state 或 actions中。

默认情况下,Redux Toolkit 添加了一个“可序列化的状态不变中间件”,如果在状态或操作中检测到​​不可序列化的值,它会向您发出警告,以帮助您避免意外犯此错误。

可以传递一些选项getDefaultMiddleware()来自定义这些中间件的行为。目前有一个ignoredActions选项,但我不认为我们可以选择忽略状态树的特定部分。包含的redux-immutable-state-invariant中间件确实有ignore部分状态的选项,所以也许我们可以添加这种方法。

我添加了https://github.com/reduxjs/redux-toolkit/issues/319看看我们是否可以添加这样的选项。

同时,您可以通过调用来关闭中间件getDefaultMiddleware({serializableCheck: false})

更新

我刚刚发布了Redux Toolkit v1.2.3,它ignoredPaths为可序列化检查中间件添加了一个选项,以允许忽略状态中的特定键路径。

再次请注意,这纯粹是为了解决行为不端的库,不应该作为常规方法使用。

于 2020-01-16T17:02:53.967 回答