从 Redux 更改为 Redux Toolkit

问题描述 投票:0回答:2

我是 React 新手,正在尝试通过编码来学习。

我需要一些代码方面的帮助/建议,将此 Redux 存储转换为 Redux Toolkit。这里我使用了一个名为 configureStore 的函数。将其更改为使用来自“@reduxjs/toolkit”的“configureStore”的好方法是什么?

这是出于学习目的。 那个“createRootReducer”来自我的 reducers.js,它结合了

const createRootReducer = (history) => combineReducers({
    articles: articlesReducer,
    selection: selectionReducer,
});

我的store.js文件:

import { createBrowserHistory } from "history";
import { createStore, compose, applyMiddleware } from "redux";
import thunk from "redux-thunk";
import { routerMiddleware } from "connected-react-router";
import createRootReducer from "./reducers";

export const history = createBrowserHistory();

const storeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;

export default function configureStore(preloadedState) {
  const store = createStore(
    createRootReducer(history),
    preloadedState,
    storeEnhancers(applyMiddleware(routerMiddleware(history), thunk))
  );
  return store;
}

javascript reactjs typescript react-redux redux-toolkit
2个回答
19
投票

提前注意:

有一个与

connected-react-router
相关的未决问题。

为了让您的设置正常工作,请确保安装

history v4.10.1
- 较新的版本会导致错误:

Uncaught 无法在状态树中找到router减速器,它必须安装在“router”下#312


1。中间件更新

redux-dev-tools
redux-thunk
已包含在 redux-toolkit 中。

如果您需要导入其他中间件,您可以使用

getDefaultMiddleware
添加它们。

如果您想添加一些自定义中间件,但仍想添加默认中间件,则

getDefaultMiddleware 非常有用:

因此,考虑到这一点,您可以从

redux-thunk
中删除
package.json


2。删除

redux
导入

您不再需要从

createStore
导入
compose
applyMiddleware
combineReducers
redux
。所有这些都在 configureStore
 提供的 
@reduxjs/toolkit
 API 内部处理。

您还可以从

redux
中删除
package.json


3.将参数从

configureStore
应用于
@reduxjs/toolkit


更新后的商店可能如下所示:

// IMPORTANT: be sure to install history v4.10.1
// see open issue: https://github.com/supasate/connected-react-router/issues/312#issuecomment-647082777
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();

// combineReducers will be handled internally by configureStore
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
});

如果您将一个对象传递给

reducer
中的
configureStore
参数,则减速器将被组合。所以你不再需要用
rootReducer
 制作 
combineReducers


这是一个演示链接


从您最初的帖子来看,您似乎只有三个中间件:

__REDUX_DEVTOOLS_EXTENSION_COMPOSE__
thunk
routerMiddleware

您看到的错误发生是因为

@redux/toolkit
为状态的正确不变性和序列化提供了额外的保护。它通过在其默认中间件中包含
redux-immutable-state-invariant
来实现这一点。

您之前的设置没有此中间件,这就是您现在只看到这些错误的原因。如果您安装了

redux-immutable-state-invariant
,您会在之前的设置中看到这些错误。

要实现与之前相同的设置,您不需要包含

defaultMiddleware
,但是,检查您的减速器并了解为什么您的状态不是不可变的和/或可序列化的,这将是一个非常好的主意。

这里的设置与您之前的设置相同,只是带有

@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();

// combineReducers will be handled internally by configureStore
const rootReducer = (history) => ({
  articles: articlesReducer,
  selection: selectionReducer,
  router: connectRouter(history)
});

const preloadedState = {};
export const store = configureStore({
  middleware: [thunk, routerMiddleware(history)],
  reducer: rootReducer(history),
  preloadedState,
});

看起来开发工具已经配置好了:Store Setup,所以我没有在这里添加它们。您应该仍然可以在浏览器的开发人员工具中使用它们。

您应该研究为什么当前状态不是不可变/可序列化的。您的状态中可能存在循环引用,或者您的状态在某处直接发生变化。这可能会导致一些严重的错误,因为 Redux 只有在状态不可变的情况下才能真正起作用。

但是,您仍然可以在当前设置中使用@redux/toolkit。


0
投票

我已经使用了 redux 所做的新更改来设置我的商店,因此您可以对此代码进行很多更改,这比您编写的代码更容易。让我们这样做吧

现在你不需要这个了

import { createStore, compose, applyMiddleware } from "redux";
import thunk from "redux-thunk";

你需要这个

 import { configureStore } from '@reduxjs/toolkit';
 import { composeWithDevTools } from '@redux-devtools/extension';

而不是像这样配置你的商店

        export default function configureStore(preloadedState) {
      const store = createStore(
        createRootReducer(history),
        preloadedState,
        storeEnhancers(applyMiddleware(routerMiddleware(history), thunk))
      );

  return store;

这样配置

首先尝试像这样组合你的 createReducer

       const rootReducer = (history) => ({
  articles: articlesReducer,
  selection: selectionReducer,
  router: connectRouter(history)
});

然后

const store = configureStore({
  reducer: createReducer,
  // for the preloaded, if you have your initial state in diffrent file
  // import and set it like this "preloadedState: myState"
  preloadedState: {},
  devTools: composeWithDevTools(),
  // the thunk middleware will be automatically provided by getDefaultMiddleware
  // and you dont need to import getDefaultMiddleware configureStore will handle it
  middleware: (getDefaultMiddleware) =>   getDefaultMiddleware().concat(routerMiddleware(history)),
});
export default store;

这个关于我如何设置商店的视频链接可能会有所帮助设置 redux

© www.soinside.com 2019 - 2024. All rights reserved.