My redux store is fairly large; Redux Devtools suggests sanitizing my larger objects to improve performance.
I've followed the docs here: https://github.com/zalmoxisus/redux-devtools-extension/blob/master/docs/Troubleshooting.md#excessive-use-of-memory-and-cpu
I've tried a number of combinations here, but none have given me the output I expect.
The current version, seen below, results in state being returned as a function, not an object. I know I'm doing something wrong, but I'm not sure what. Any guidance would be deeply appreciated.
Here's my store.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
)
Second try
I've made a couple of updates, and can now see the sanitizers' effect in devtools - depending on placement in my createStore function. Unfortunately this changes my composeEnhancers behavior (fires, or does doesn't fire depending on placement)
// 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
})
)
Finally, persistence ftw!
I hate giving up; figured it out after rereading all the documentation posted by @markerikson. Always read the docs :'(
This may not be of use to anyone using configureStore
and Redux Toolkit
, but I'm documenting it regardless.
My big mistake was that actionSanitizer
and stateSanitizer
are Devtools Extension options, and should be added as such. Feel a fool, but at least I won't forget it.
The only thing left to do is implement redux-devtools-extension to avoid using window.__SOMEFUNC__
as suggested by markerikson.
The actual solution:
'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