Created
December 16, 2016 12:04
-
-
Save krstffr/245fe83885b597aabaf06348220c2fe9 to your computer and use it in GitHub Desktop.
Debouncing redux thunk actions.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// A common redux pattern when dealing with async functions is to use thunk. | |
// This usually means your action returns a new function instead of an action object, | |
// and the thunk middleware will make it all work. Example: | |
const asyncAction = () => dispatch => setTimeout(() => dispatch(someOtherAction()), 10000); | |
// Now: maybe that async stuff going on is calling some API which you don't want to overload | |
// with request, and that's what debounce is for. | |
// This is an example of a debounced function which will only be calleable once every second. | |
import { debounce } from 'lodash'; | |
const debouncedFn = debounce(() => callApi(), 1000, { leading: true, trailing: false }); | |
// This will only call the function once since its debounced: | |
debouncedFn(); | |
debouncedFn(); | |
debouncedFn(); | |
// If you want to do this in your redux thunk actions, you need to think about a few things. | |
// 1. In our example thunk action above the returned function is defined every time the outer | |
// function is called, meaning that if we were to wrap it in debounce() it would just call a | |
// new version of that function every time, which would of course call it every time. | |
// 2. Ehm, that's really the only thing you need to think about! | |
// How do we solve this? Define the inner function outside of the wrapping function of course. | |
// So: this will NOT work: | |
const asyncActionNOTDebounced = () => debounce(dispatch => setTimeout(() => dispatch(someOtherAction()), 10000), 1000); | |
// But this will work since the inner function is only "created" once: | |
const innerFunction = debounce(dispatch => setTimeout(() => dispatch(someOtherAction()), 10000), 1000); | |
const asyncActionDebounced = () => innerFunction; |
const innerFunction = debounce((dispatch, ...args) => setTimeout(() => dispatch(someOtherAction(...args)), 10000), 1000);
const asyncActionDebounced = (...args) => dispatch => innerFunction(dispatch, ...args);
Thank you @panayi. The solution worked for my case as well. I had to pull the debounce out of the mapDispatchToProps
to prevent it from re-initializing again and again. I did not use setTimeout
though, called the API method directly.
Thank you so much! :D
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Excellent! Very helpful. What if you want to pass in arguments to
innerFunction
though? If you have a payload or something?