如何将状态清理器与 React-Redux 中的现有中间件相结合



我的 redux 存储相当大;Redux Devtools建议清理我的较大对象以提高性能。

我在这里遵循了文档:https://github.com/zalmoxisus/redux-devtools-extension/blob/master/docs/Troubleshooting.md#excessive-use-of-memory-and-cpu

我在这里尝试了许多组合,但没有一个能给我预期的输出。

当前版本(如下所示(导致状态作为函数而不是对象返回。我知道我做错了什么,但我不确定是什么。任何指导将不胜感激。

这是我的商店.js:


'use strict'
// libraries
import { createStore, applyMiddleware, compose } from 'redux'
// middleware
import logger from 'redux-logger'
import thunk from 'redux-thunk'
// reducers
import reducer from './reducers'
const withLogger = false ? (thunk, logger) : thunk
const isProd = process.env.NODE_ENV === 'production'
const middleware = isProd ? thunk : withLogger
const composeEnhancers = isProd
? compose
: window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose
// sanitizers to keep redux devtools from using excessive memory
const actionSanitizer = action =>
!!action.id
&& action.type === `RECEIVE_${action.id.toString().toUpperCase()}_COLLECTION`
? { ...action, data: '<<LONG_BLOB>>' }
: action
const store = createStore(
reducer,
composeEnhancers(applyMiddleware(middleware)),

// The addition of this code breaks my store
window.__REDUX_DEVTOOLS_EXTENSION__
&& window.__REDUX_DEVTOOLS_EXTENSION__({
actionSanitizer,
stateSanitizer: state =>
state.data ? { ...state, data: '<<LONG_BLOB>>' } : state
})
// End breaking code
)

第二次尝试

我已经进行了一些更新,现在可以在devtools中看到清理器的效果 - 取决于我的createStore函数中的位置。不幸的是,这改变了我的作曲增强器行为(根据位置触发或不触发(


// middleware with or without logger
const middlewareEnhancer =
true || ENV === 'production' // change to false to prevent logger output
? applyMiddleware(thunk, logger)
: applyMiddleware(thunk)
// sanitizers to keep redux devtools from using excessive memory
const actionSanitizer = action =>
!!action.id
&& action.type === `RECEIVE_${action.id.toString().toUpperCase()}_COLLECTION`
? { ...action, data: '<<LONG_BLOB>>' }
: action
// compose
const composeEnhancers =
window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__(middlewareEnhancer) ||
compose(middlewareEnhancer)
const store = createStore(
// createStore signature > reducer, preLoadedState, enhancer
rootReducer,
// devtools extension works when I place it here per the examples in docs
// BUT composed enhancers fail
// Obviously, since the format wouldn't match the createStore signature
// I have no idea how `__REDUX_DEVTOOLS_EXTENSION__` should be used in conjunction with composeEnhancers
undefined,
composeEnhancers,
// devtools extension fails when placed here
// composed enhancers run
window.__REDUX_DEVTOOLS_EXTENSION__
&& window.__REDUX_DEVTOOLS_EXTENSION__({
actionSanitizer,
stateSanitizer: state =>
state.data ? { ...state, data: '<<LONG_BLOB>>' } : state
})
)

最后,坚持不懈!

我讨厌放弃;在重读了@markerikson发布的所有文档后想通了。始终阅读文档:'(

这可能对任何使用configureStoreRedux Toolkit的人都没有用,但无论如何我都会记录它。

我最大的错误是actionSanitizerstateSanitizer是Devtools扩展选项,应该这样添加。感觉自己是个傻瓜,但至少我不会忘记它。

剩下的唯一要做的就是实现redux-devtools-extension,以避免使用markerikson建议的window.__SOMEFUNC__

实际解决方案:

'use strict'
// libraries
import { createStore, applyMiddleware, compose } from 'redux'
// middleware
import logger from 'redux-logger'
import thunk from 'redux-thunk'
// reducers
import rootReducer from './reducers'
// middleware with or without logger
const middlewareEnhancer =
true || ENV === 'production' // change to false to prevent logger output
? applyMiddleware(thunk, logger)
: applyMiddleware(thunk)
// sanitizers to keep redux devtools from using excessive memory
const actionSanitizer = action =>
!!action.id
&& action.type === `RECEIVE_${action.id.toString().toUpperCase()}_COLLECTION`
? { ...action, data: '<<LONG_BLOB>>' }
: action
// compose
const composeEnhancers =
window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__({
// add sanitizers here as devtools options
// see https://github.com/zalmoxisus/redux-devtools-extension/tree/94f7e53800f4665bddc9b7438c5cc75cfb4547cc#12-advanced-store-setup
// section 1.2
actionSanitizer,
stateSanitizer: state =>
state.data ? { ...state, data: '<<LONG_BLOB>>' } : state
}) || compose
const enhancer = composeEnhancers(middlewareEnhancer)
const store = createStore(rootReducer, undefined, enhancer)
export default store

作为第一个观察,这一行似乎是错误的:

const withLogger = false ? (thunk, logger) : thunk

我强烈建议您首先切换到使用我们官方 Redux Toolkit 包中的configureStore功能,该包为您处理商店设置过程。 如果需要,仍可以从那里将 DevTools 配置选项传递给configureStore()

只是为了完成那些使用 reduxtoolkit的答案,这是一个对我来说很有效的示例条目。

const devToolsConfiguration = {
actionSanitizer: (action) => {
switch (true) {
case action.type.includes(RESOLVED):
return typeof action.payload !== 'undefined'
? { ...action, payload: '<<LONG_BLOB>>' }
: { ...action, results: '<<LONG_BLOB>>' };
/* ... more entries */
default:
return action;
}
},
stateSanitizer: (state) =>
state.data?.matrix
? { ...state, data: { ...state.data, matrix: '<<LONG_BLOB>>' } }
: state,
};

然后,我在工具包的configureStore函数中引用配置:

const store = configureStore({
reducer: persistedReducer,
middleware: (getDefaultMiddleware) =>
getDefaultMiddleware({
thunk: false,
serializableCheck: false,
immutableCheck: false,
}).prepend(middlewares),
preloadedState: initialState,
devTools: devToolsConfiguration,  // <<< here
});

最新更新