简体   繁体   English

从 Redux 更改为 Redux 工具包

[英]Changing from Redux to Redux Toolkit

I am new to React and am trying to learn by coding.我是 React 的新手,正在尝试通过编码来学习。

I need some help/advice with the code, with converting this Redux store to Redux Toolkit.我需要一些关于代码的帮助/建议,将这个 Redux 存储转换为 Redux Toolkit。 Here I'm using a function called configureStore .在这里,我使用了一个名为configureStore的函数。 What is good way of changing this into using the 'configureStore' which comes from '@reduxjs/toolkit'?将其更改为使用来自“@reduxjs/toolkit”的“configureStore”的好方法是什么?

This is for learning purposes.这是出于学习目的。 That 'createRootReducer' comes from my reducers.js which combines 'createRootReducer' 来自我的 reducers.js,它结合了

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

My store.js file:我的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; }

Note in advance:提前注意:

There is an open issue related to connected-react-router .有一个与connected-react-router相关的未解决问题。

In order to get your setup to work, make sure to install history v4.10.1 - newer versions are causing errors:为了让您的设置正常工作,请确保安装history v4.10.1 - 较新的版本会导致错误:

Uncaught Could not find router reducer in state tree, it must be mounted under "router" #312 未捕获在状态树中找不到路由器减速器,它必须安装在“路由器”下 #312


1. Middleware updates 1.中间件更新

The redux-dev-tools and redux-thunk are already included in redux-toolkit. redux-dev-toolsredux-thunk已经包含在 redux-toolkit 中。

If you need to import additional middleware, you can add these in by using getDefaultMiddleware .如果您需要导入其他中间件,可以使用getDefaultMiddleware添加这些中间件。

getDefaultMiddleware is useful if you want to add some custom middleware, but also still want to have the default middleware added as well:如果您想添加一些自定义中间件,但仍希望添加默认中间件,getDefaultMiddleware 很有用:

So with this in mind, you can remove redux-thunk from your package.json .所以考虑到这一点,你可以从你的package.json中删除redux-thunk


2. Remove redux imports 2.删除redux导入

You no longer need to import createStore , compose , applyMiddleware , combineReducers from redux .您不再需要从redux导入createStorecomposeapplyMiddlewarecombineReducers All of these are handled internally in the configureStore API provided by @reduxjs/toolkit .所有这些都在@reduxjs/toolkit提供的configureStore API 内部处理。

You can also remove redux from package.json .你也可以从package.json中移除redux


3. Apply args to configureStore from @reduxjs/toolkit . 3. 从@reduxjs/toolkit应用 args 到configureStore


The updated store could look like this:更新后的商店可能如下所示:

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

If you pass an object to the reducer param in configureStore , the reducers will be combined.如果您将对象传递给configureStore中的reducer参数,则 reducer 将被合并。 So you no longer need to make a rootReducer with combineReducers所以你不再需要用combineReducers制作一个rootReducer


Here is a demo link .这是一个演示链接


From your initial post, it looks like you only had three middlewares:从您最初的帖子来看,您似乎只有三个中间件:

__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ , thunk , and routerMiddleware . __REDUX_DEVTOOLS_EXTENSION_COMPOSE__thunkrouterMiddleware

The errors you are seeing happen because @redux/toolkit is offering extra protection for correct immutability and serialization of your state.您看到的错误发生是因为@redux/toolkit为您的状态的正确不变性和序列化提供了额外的保护。 It does so by including redux-immutable-state-invariant in its default middleware.它通过在其默认中间件中包含redux-immutable-state-invariant来实现。

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.如果你安装了redux-immutable-state-invariant ,你会在之前的设置中看到这些错误。

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.要实现与之前相同的设置,您不需要包含defaultMiddleware ,但是通过您的 reducer 并查看为什么您的状态不是不可变和/或可序列化的原因是一个非常好的主意。

Here is an identical setup to what you had before, only with @redux/toolkit这是与您之前的设置相同的设置,仅使用@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,
});

It looks like the dev tools are configured already: Store Setup , so I did not add them here.看起来开发工具已经配置: Store Setup ,所以我没有在这里添加它们。 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.这可能会导致一些令人讨厌的错误,因为 Redux 只有在状态不可变的情况下才能真正起作用。

However, you can still use @redux/toolkit with your current setup.但是,您仍然可以在当前设置中使用 @redux/toolkit。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM