From 65ae949d9637e7ca0b5e2c0da25068c7b88cc1fe Mon Sep 17 00:00:00 2001 From: Zalmoxisus Date: Wed, 18 Jan 2017 22:30:27 +0200 Subject: [PATCH] [Docs] Synthetic events troubleshooting Fix #275 and #287. --- docs/Troubleshooting.md | 49 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/docs/Troubleshooting.md b/docs/Troubleshooting.md index 1fee1d8d..e381ab84 100644 --- a/docs/Troubleshooting.md +++ b/docs/Troubleshooting.md @@ -29,3 +29,52 @@ const store = createStore(reducer, preloadedState, compose( ``` Where `batchedSubscribe` is `redux-batched-subscribe` store enhancer. + +### It fails to serialize data when [passing synthetic events](https://github.com/zalmoxisus/redux-devtools-extension/issues/275) or [calling an action directly with `redux-actions`](https://github.com/zalmoxisus/redux-devtools-extension/issues/287) + +React synthetic event cannot be reused for performance reason. So, it's not possible to serialize event objects you pass to action payloads. + +1. The best solution is not to pass the whole event object to reducers, but the data you need: + ```diff + function click(event) { + return { + type: ELEMENT_CLICKED, + - event: event + + value: event.target.value + }; + } + ``` + +2. Another solution would be to use `event.persist()` (in the example above) as suggested in [React Docs](https://facebook.github.io/react/docs/events.html#event-pooling), but it will consume RAM while not needed. + +3. If you still need to pass it to an action, you can override this key of the stringified payload in your action creator, by adding a custom `toJSON` function (which will be called by the extension before accessing the object): + + ```diff + function increment(event) { + return { + type: INCREMENT_COUNTER, + event, + + toJSON: function (){ + + return { ...this, event: '[Event]' }; + + } + }; + } + ``` + Note that it shouldn't be arrow function as we want to have access to the function's `this`. + + As we don't have access to the original object, skipping and recomputing actions during hot reloading will not work in this case. So better to use the required value from the event than the whole event object. + +4. If you don't want to add `toJSON` to action creators, a solution to prevent this, would be to use `serialize` parameter and to check if it's an instance of `SyntheticEvent` like so: + ```js + import SyntheticEvent from 'react/lib/SyntheticEvent'; + // ... + + const store = createStore(rootReducer, window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__({ + serialize: { + replacer: (key, value) => { + if (value && value instanceof SyntheticEvent) return '[Event]'; + return value; + } + } + })); + ```