如何在React-Redux中将状态清理程序与现有中间件结合

anauzrmj  于 2022-11-24  发布在  React
关注(0)|答案(2)|浏览(119)

我的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函数中的位置。不幸的是,这改变了我的composeEnhancers行为(触发,或不触发,取决于位置)

// 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
zdwk9cvp

zdwk9cvp1#

作为第一次观察,这行似乎是错误的:
const withLogger = false ? (thunk, logger) : thunk
我强烈建议您首先切换到使用the configureStore function from our official Redux Toolkit package,它为您处理存储设置过程。如果需要,您仍然可以从那里将DevTools配置选项传递给configureStore()

pw136qt2

pw136qt22#

为了让那些使用redux toolkit的人能更好地回答这个问题,这里有一个很好的例子。

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

相关问题