A common conundrum in today’s front-end framework world is knowing when and how to take certain asynchronous actions, such as persisting data to a backend. If we’re using a state management library like Redux, we might be further confused as to where without our Redux code we might put this logic.
For the purposes of this blog post, let’s assume we are using React with Redux and want to periodically save our state data to a backend. We have elected to use debouncing to do this, meaning we’d like to perform the save action after our state hasn’t changed for a certain amount of time.
So, what are our options when using React with Redux? I think the following list covers it:
Note: I think all of these are actually legitimate ways except performing the save in a reducer. Reducers really should be pure functions and performing data fetching from within the reducer is a side effect.
As I mentioned above, I think most of these approaches could work fine, but I especially like the middleware approach. It nicely isolates your saving code, can selectively define which actions cause saving to start, doesn’t require installing thunk middleware if you’re not already using it, and doesn’t require you to include a component that exists only to handle saving.
First, we can create a saveDebounce
function that will be called by our middleware. To implement debouncing, we’ll make use of setTimeout
and clearTimeout
.
let saveTimer;
let debounceTime = 10000; // 10 seconds
const saveDebounce = data => {
if (saveTimer) {
clearTimeout(saveTimer);
}
saveTimer = setTimeout(() => {
// Use request library of choice here
fetch('my-api-endpoint', {
method: 'POST',
body: JSON.stringify(data),
});
}, debounceTime);
};
Next, the actual middleware, which is pretty simple.
export const dataSaver = store => next => action => {
saveDebounce(store.getState());
return next(action);
};
As a user is modifying state, the saveDebounce
function will clear any previous timeout and start a new one. Only when the user hasn’t changed state for 10 seconds will our fetch
actually be called.
Finally, we need to register our middleware with Redux. This is done when we create our store
.
#redux