React 工具包和 redux-first-router

React toolkit and redux-first-router

我正在深入研究 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.

如果路由有一个 'thunk' 属性 定义,我可以看到这源于路由定义:PROFILE: { path: "/profile/:username", thunk: fetchUserData },

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

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

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

根据该错误消息并阅读 Redux-First-Router 源代码,它看起来像库 is indeed attempting to store thunk functions in the Redux store. This is a problem, because we specifically instruct users to never put non-serializable values like functions in state or actions

默认情况下,Redux Toolkit 添加 a "serializable state invariant middleware" 如果在状态或操作中检测到​​不可序列化的值时会警告您,以帮助您避免不小心犯此错误。

可以pass some options to getDefaultMiddleware() to customize the behavior of these middlewares。目前有一个 ignoredActions 选项,但我不认为我们可以选择忽略状态树的特定部分。包含的 redux-immutable-state-invariant 中间件确实有一个 ignore 选项用于部分状态,所以也许我们可以添加该方法。

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

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

更新

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

再次请注意,这纯粹是解决行为不当库的逃生通道,不应作为常规方法使用。