diff --git a/source/debounceFormChangeActions.js b/source/debounceFormChangeActions.js new file mode 100644 index 000000000..66d1dbfbe --- /dev/null +++ b/source/debounceFormChangeActions.js @@ -0,0 +1,34 @@ +// Thank you, github.com/ryanseddon/redux-debounced + +export default () => { + let timers = {} + + let time = 500 + + let middleware = () => dispatch => action => { + let { type } = action + + let key = type + + const shouldDebounce = key === '@@redux-form/CHANGE' + + if (!shouldDebounce) { + return dispatch(action) + } + + if (timers[key]) { + clearTimeout(timers[key]) + } + + dispatch(action) + return new Promise(resolve => { + timers[key] = setTimeout(() => { + resolve(dispatch({ type: 'USER_INPUT_UPDATE' })) + }, time) + }) + } + + middleware._timers = timers + + return middleware +} diff --git a/source/entry.js b/source/entry.js index 37c45582d..f425367a1 100644 --- a/source/entry.js +++ b/source/entry.js @@ -1,10 +1,11 @@ import React from 'react' import { render } from 'react-dom' -import { compose, createStore } from 'redux' +import { compose, createStore, applyMiddleware } from 'redux' import App from './containers/App' import reducers from './reducers' import DevTools from './DevTools' import { AppContainer } from 'react-hot-loader' +import debounceFormChangeActions from './debounceFormChangeActions' import computeThemeColours from './components/themeColours' import { getIframeOption, getUrl } from './utils' @@ -13,7 +14,15 @@ let initialStore = { themeColours: computeThemeColours(getIframeOption('couleur')) } -let store = createStore(reducers, initialStore, compose(DevTools.instrument())) +let createStoreWithMiddleware = applyMiddleware(debounceFormChangeActions())( + createStore +) + +let store = createStoreWithMiddleware( + reducers, + initialStore, + compose(DevTools.instrument()) +) let anchor = document.querySelector('#js') render(, anchor) diff --git a/source/reducers.js b/source/reducers.js index 319f34bd2..c371c3648 100644 --- a/source/reducers.js +++ b/source/reducers.js @@ -51,7 +51,7 @@ export let reduceSteps = (tracker, flatRules, answerSource) => ( if (!state.parsedRules) state.parsedRules = parseAll(flatRules) if ( - ![START_CONVERSATION, STEP_ACTION, '@@redux-form/CHANGE'].includes( + ![START_CONVERSATION, STEP_ACTION, 'USER_INPUT_UPDATE'].includes( action.type ) ) @@ -76,7 +76,7 @@ export let reduceSteps = (tracker, flatRules, answerSource) => ( situationWithDefaults(state) ) - if (action.type === '@@redux-form/CHANGE') { + if (action.type === 'USER_INPUT_UPDATE') { return { ...state, analysis, situationGate: situationWithDefaults(state) } }