最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Changing from Redux to Redux Toolkit - Stack Overflow

programmeradmin11浏览0评论

I am new to React and am trying to learn by coding.

I need some help/advice with the code, with converting this Redux store to Redux Toolkit. Here I'm using a function called configureStore. What is good way of changing this into using the 'configureStore' which es from '@reduxjs/toolkit'?

This is for learning purposes. That 'createRootReducer' es from my reducers.js which bines

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

My store.js file:

import { createBrowserHistory } from "history";
import { createStore, pose, 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__ || pose;

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

I am new to React and am trying to learn by coding.

I need some help/advice with the code, with converting this Redux store to Redux Toolkit. Here I'm using a function called configureStore. What is good way of changing this into using the 'configureStore' which es from '@reduxjs/toolkit'?

This is for learning purposes. That 'createRootReducer' es from my reducers.js which bines

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

My store.js file:

import { createBrowserHistory } from "history";
import { createStore, pose, 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__ || pose;

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

Share Improve this question edited Jun 21, 2022 at 14:56 Peter Mortensen 31.6k22 gold badges110 silver badges133 bronze badges asked Oct 8, 2021 at 22:04 user10727653user10727653
Add a ment  | 

2 Answers 2

Reset to default 20

Note in advance:

There is an open issue related to connected-react-router.

In order to get your setup to work, make sure to install history v4.10.1 - newer versions are causing errors:

Uncaught Could not find router reducer in state tree, it must be mounted under "router" #312


1. Middleware updates

The redux-dev-tools and redux-thunk are already included in redux-toolkit.

If you need to import additional middleware, you can add these in by using getDefaultMiddleware.

getDefaultMiddleware is useful if you want to add some custom middleware, but also still want to have the default middleware added as well:

So with this in mind, you can remove redux-thunk from your package.json.


2. Remove redux imports

You no longer need to import createStore, pose, applyMiddleware, bineReducers from redux. All of these are handled internally in the configureStore API provided by @reduxjs/toolkit.

You can also remove redux from package.json.


3. Apply args to configureStore from @reduxjs/toolkit.


The updated store could look like this:

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

// bineReducers 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
});

If you pass an object to the reducer param in configureStore, the reducers will be bined. So you no longer need to make a rootReducer with bineReducers


Here is a demo link.


From your initial post, it looks like you only had three middlewares:

__REDUX_DEVTOOLS_EXTENSION_COMPOSE__, thunk, and routerMiddleware.

The errors you are seeing happen because @redux/toolkit is offering extra protection for correct immutability and serialization of your state. It does so by including redux-immutable-state-invariant in its default middleware.

Your prior setup did not have this middleware, and that's why you are only seeing these errors now. If you had redux-immutable-state-invariant installed, you would've seen these errors in your previous setup.

To achieve an identical setup to what you had before, you do not need to include the defaultMiddleware, however it would be a very good idea to go through your reducers and see why your state is not immutable and/or serializable.

Here is an identical setup to what you had before, only with @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();

// bineReducers 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,
});

It looks like the dev tools are configured already: Store Setup, so I did not add them here. You should be able to still use them in your browser's developer tools.

You should look into why your current state is not immutable/serializable. It is possible there are circular references in your state, or your state is being directly mutated somewhere. This can lead to some nasty bugs down the line, because Redux only truly works if the state is immutable.

However, you can still use @redux/toolkit with your current setup.

I have used the new changes made by redux to setup my store, so there is a lot of changes you can do to this code which is more easier than the one you wrote. let do this

Now you don't need this

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

You Need This

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

Instead configuring your store like this

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

  return store;

Configure it this way

first try to bine your createReducer like this

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

and then

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: poseWithDevTools(),
  // 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;

and this video link on how i set my store may help setup redux

发布评论

评论列表(0)

  1. 暂无评论