переход с redux на redux toolkit

#javascript #reactjs #typescript #react-redux #redux-toolkit

Вопрос:

Новичок в Reactjs, пытаюсь учиться с помощью кодирования, мне нужна помощь/совет с кодом, с преобразованием этого хранилища Redux в инструментарий Redux, здесь я использую функцию под названием configureStore, каков хороший способ изменить это на использование «Магазина конфигурации», который исходит от «@reduxjs/инструментарий «это для целей обучения, что «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;
} 

Ответ №1:

Обратите внимание заранее:

Существует открытый вопрос, связанный с connected-react-router .

Для того, чтобы ваша программа установки заработала, убедитесь, что она установлена history v4.10.1 — новые версии вызывают ошибки:

https://github.com/supasate/connected-react-router/issues/312#issuecomment-647082777


1. Обновления промежуточного программного обеспечения

redux-dev-tools И redux-thunk уже включены в redux-инструментарий.

Если вам нужно импортировать дополнительное промежуточное программное обеспечение, вы можете добавить их с помощью getDefaultMiddleware .

getDefaultMiddleware полезно, если вы хотите добавить какое-либо пользовательское промежуточное программное обеспечение, но также хотите добавить промежуточное программное обеспечение по умолчанию:

Итак, имея это в виду, вы можете удалить redux-thunk из своего package.json .


2. Удалите redux импорт

Вам больше не нужно импортировать createStore , compose , applyMiddleware , combineReducers из redux . Все это обрабатывается внутренне в configureStore API, предоставляемом компанией @reduxjs/toolkit .

Вы также можете удалить 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


Вот демонстрационная ссылка.


Обновить

Я хотел отметить, что, судя по вашему первоначальному сообщению, у вас было только 3 промежуточных программного обеспечения:

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

Похоже, что инструменты разработки уже настроены: https://redux-toolkit.js.org/usage/usage-guide#store-setup, поэтому я не стал добавлять их сюда. Вы все равно сможете использовать их в инструментах разработчика вашего браузера.

Вам следует разобраться, почему ваше текущее состояние не является неизменяемым/сериализуемым. Возможно, в вашем состоянии есть циклические ссылки, или ваше состояние где-то напрямую мутирует. Это может привести к некоторым неприятным ошибкам в будущем, потому что redux действительно работает только в том случае, если состояние неизменяемо.

Тем не менее, вы все равно можете использовать @redux/toolkit с вашей текущей настройкой.

Комментарии:

1. я сделал в точности так, как вы сказали, но получил новый тип ошибки: 1: redux-toolkit.esm.js:301 Неперехваченная ошибка диапазона: Максимальный размер стека вызовов превышен в свойствах трека (redux-toolkit.esm.js:301) в свойствах трека (redux-toolkit.esm.js:312) 2: Неперехваченная ошибка диапазона: Максимальный размер стека вызовов превышен в свойствах трека (redux-toolkit.esm.js:301) в свойствах трека (redux-toolkit.esm.js:301) в свойствах трека (redux-toolkit. esm. js: 312)

2. мои редукторы и действия закодированы в старом стиле redux, а не в наборе инструментов redux, может ли он оставаться таким, пока я конвертирую магазин в набор инструментов redux ?

3. Существующие редукторы и действия работают с инструментарием redux. Ошибка, которую вы опубликовали, предполагает, что состояние изменяется. Ошибка выбрасывается из immutableStateInvariantMiddleware . Возможно, в вашем состоянии есть циклические ссылки, вызывающие бесконечную рекурсию в промежуточном программном обеспечении. Мне трудно сказать, не видя вашей кодовой базы. Вы можете попробовать и посмотреть, исчезнет ли ошибка, изменив getDefaultMiddleware() значение на getDefaultMiddleware({ immutableCheck: false }) . Если это действительно исчезнет, вам следует проверить и посмотреть, где происходит изменение состояния. Состояние восстановления всегда должно быть неизменным.

4. это также дает : В действии, в пути: было обнаружено несериализуемое значение: payload . Значение: Взгляните на логику, которая отправила это действие: {тип: ‘GET_FLOORPLAN’, полезная нагрузка: img} (см. redux.js.org/faq/… ) (Чтобы разрешить несериализуемые значения, см.: redux-toolkit.js.org/usage/… )

5. я решил эти ошибки с помощью этого : экспорт const store = configureStore({ промежуточное программное обеспечение: (getDefaultMiddleware) => getDefaultMiddleware({ Неизменяемая проверка: ложь, сериализуемая проверка: ложь, }).concat(routerMiddleware(история)), редуктор: rootReducer(история), предварительно загруженное состояние, }); но это неправильный способ, есть ли хороший способ проверить, где состояние изменено, быстрый способ, чтобы мне действительно это сойдет с рук?