From 033327cbab13d1c0240510182d563ecc1430cea7 Mon Sep 17 00:00:00 2001 From: Chris Bobbe Date: Wed, 29 Jul 2020 12:16:56 -0700 Subject: [PATCH] redux: When logging, show Immutable parts of state as plain JS objects. Immutable.JS objects come with extra properties and hierarchies that are an obstacle to debugging; we only care about the data the objects contain. Redux themselves point out the obstacle [0], but I noticed it in my own debugging before I saw that doc. Redux recommends a browser extension, but I think it's better to build a solution into our code. So, do a simple transformation in our `redux-logger` middleware, with an implementation informed by a `redux-logger` doc [1]. That example uses `Iterable.isIterable`, which seems like the thing people did before `Iterable.isImmutable` arrived [2]. The `isImmutable` doc [3] says, "True if `maybeImmutable` is an Immutable Collection or Record". I checked, and Collection [4] and Record [5] instances both have a `.toJS` method. We don't use any Records yet, but we want to avoid nasty surprises if we ever do. [0] https://github.com/reduxjs/redux/blob/master/docs/recipes/UsingImmutableJS.md#difficult-to-debug [1] https://github.com/LogRocket/redux-logger#transform-immutable-with-combinereducers [2] https://stackoverflow.com/a/31919411/6792075; see also PR https://github.com/immutable-js/immutable-js/pull/1113; issue https://github.com/immutable-js/immutable-js/issues/566 [3] https://immutable-js.github.io/immutable-js/docs/#/isImmutable [4] https://immutable-js.github.io/immutable-js/docs/#/Collection/toJS [5] https://immutable-js.github.io/immutable-js/docs/#/Record/toJS --- src/boot/store.js | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/boot/store.js b/src/boot/store.js index 1147661b7ce..b428e8bdb63 100644 --- a/src/boot/store.js +++ b/src/boot/store.js @@ -240,6 +240,20 @@ function listMiddleware() { // and ours: // https://github.com/zulip/zulip-mobile/blob/master/docs/howto/debugging.md#redux-logger createLogger({ + stateTransformer: state => { + // Beware: errors thrown in here will silently drop actions. + const newState = {}; + Object.keys(state).forEach(key => { + if (Immutable.isImmutable(state[key])) { + // Make things like `state.narrows` appear as plain + // JS objects in the logs (much easier to read) + newState[key] = state[key].toJS(); + } else { + newState[key] = state[key]; + } + }); + return newState; + }, duration: true, // Example options to add for more focused information, depending on // what you're investigating; see docs/howto/debugging.md (link above).