注意:
目前有一个与 connected-react-router
相关的问题需要解决。
为了使您的设置正常工作,请确保安装 history v4.10.1
- 更高版本会导致错误:
Uncaught Could not find router reducer in state tree, it must be mounted under "router" #312
1. 中间件更新
redux-toolkit
已经包含了 redux-dev-tools
和 redux-thunk
。
如果您需要导入其他中间件,可以使用 getDefaultMiddleware
来添加它们。
如果您想要添加一些自定义中间件,但仍然希望添加默认中间件,那么 getDefaultMiddleware
是非常有用的:
因此,在这种情况下,您可以从 package.json
中删除 redux-thunk
。
2. 删除 redux
导入
您不再需要从 redux
导入 createStore
、compose
、applyMiddleware
和 combineReducers
。所有这些都由 @reduxjs/toolkit
提供的 configureStore
API 在内部处理。
您还可以从 package.json
中删除 redux
。
3. 从 @reduxjs/toolkit
的 configureStore
应用参数。
更新后的 store 可以像这样:
import { createBrowserHistory, History } from "history";
import { configureStore } from "@reduxjs/toolkit";
import {
routerMiddleware,
connectRouter,
RouterState
} from "connected-react-router";
import selectionReducer from "./reducers/selection";
import articlesReducer from "./reducers/articles";
import todosReducer, { I_TodoState } from "./reducers/todos";
export const history = createBrowserHistory();
const rootReducer = (history: History<any>) => ({
articles: articlesReducer,
selection: selectionReducer,
todos: todosReducer,
router: connectRouter(history)
});
const preloadedState = {};
export const store = configureStore({
middleware: (getDefaultMiddleware) =>
getDefaultMiddleware().concat(routerMiddleware(history)),
reducer: rootReducer(history),
preloadedState
});
如果你在
configureStore
的
reducer
参数中传递一个对象,那么reducers将被组合。所以你不再需要使用
combineReducers
创建一个
rootReducer
。
这是一个演示链接:
demo link
从你最初的帖子看,你只有三个中间件:
__REDUX_DEVTOOLS_EXTENSION_COMPOSE__
、
thunk
和
routerMiddleware
。
你看到的错误是因为
@redux/toolkit
为了正确保护你的状态不可变和序列化而提供额外的保护。它通过在默认的中间件中包含
redux-immutable-state-invariant
来实现这一点。
你之前的设置没有这个中间件,这就是为什么你现在只看到这些错误。如果你安装了
redux-immutable-state-invariant
,你会在之前的设置中看到这些错误。
要实现与之前相同的设置,你不需要包括
defaultMiddleware
,但检查你的reducers并了解为什么你的状态不可变和/或可序列化是一个非常好的主意。
下面是一个与你之前完全相同的设置,只是加入了
@redux/toolkit
。
import { configureStore } from '@reduxjs/toolkit';
import { routerMiddleware, connectRouter } from 'connected-react-router';
import { createBrowserHistory } from 'history';
import thunk from 'redux-thunk';
import { rootReducer } from './reducer';
export const history = createBrowserHistory();
const rootReducer = (history) => ({
articles: articlesReducer,
selection: selectionReducer,
router: connectRouter(history)
});
const preloadedState = {};
export const store = configureStore({
middleware: [thunk, routerMiddleware(history)],
reducer: rootReducer(history),
preloadedState,
});
看起来开发工具已经配置好了:存储设置,所以我没有在这里添加它们。您仍应该能够在浏览器的开发工具中使用它们。
您应该查看为什么当前状态不是不可变的/可序列化的。这可能是由于状态中存在循环引用,或者状态在某个地方被直接修改。这可能会导致一些令人讨厌的错误,因为 Redux 只有在状态不可变时才真正发挥作用。
但是,您仍然可以在当前设置中使用 @redux/toolkit。
immutableStateInvariantMiddleware
抛出的。也许在您的状态中存在循环引用,导致中间件中出现无限递归。如果没有看到您的代码库,我很难判断。您可以尝试更改getDefaultMiddleware()
为getDefaultMiddleware({ immutableCheck: false })
,并查看错误是否消失。如果确实消失了,则应检查并查看状态在何处发生了突变。Redux状态应始终是不可变的。 - Dan Kreiger