Debouncing Input with Redux Middleware
Demonstrate the use of custom middleware to debounce an input field action to prevent rapid firing of actions in a Redux-managed state.
const debounceMiddleware = ({ dispatch, getState }) => next => action => {
if (action.meta && action.meta.debounce) {
const { key, time } = action.meta.debounce;
if (time) {
if (debounceMiddleware.debounceTimers[key]) {
clearTimeout(debounceMiddleware.debounceTimers[key]);
}
debounceMiddleware.debounceTimers[key] = setTimeout(
() => next(action),
time
);
}
} else {
return next(action);
}
};
debounceMiddleware.debounceTimers = {};
// ... Often useful to combine with reducers, actions, and other middlewares ...
Custom Redux middleware named debounceMiddleware which accepts actions with a meta field specifying debounce details. It uses setTimeout to delay action dispatching.
// Your actions.js
export const setInputValue = (value) => ({
type: 'SET_INPUT_VALUE',
payload: value,
meta: { debounce: { key: 'setInputValue', time: 500 } }
});
Defines an action creator with a debounce configuration in the meta object. The 'SET_INPUT_VALUE' action will be debounced for 500ms.
// Your Component.jsx (React example)
import React, { useState } from 'react';
import { useDispatch } from 'react-redux';
import { setInputValue } from './actions';
const SearchInput = () => {
const dispatch = useDispatch();
const [inputValue, setInput] = useState('');
const handleInputChange = (e) => {
const value = e.target.value;
setInput(value);
dispatch(setInputValue(value));
};
return (
<input
value={inputValue}
onChange={handleInputChange}
placeholder='Type to search...'
/>
);
};
export default SearchInput;
A React component demonstrating how to use the 'setInputValue' action with the debounce middleware in a controlled input.
/* Your reducer.js */
export const inputReducer = (state = '', action) => {
switch (action.type) {
case 'SET_INPUT_VALUE':
return action.payload;
default:
return state;
}
};
A Redux reducer that responds to the 'SET_INPUT_VALUE' action to update state based on the debounced input value.
/* Your applyMiddleware call in the Redux store setup */
import { createStore, applyMiddleware } from 'redux';
import rootReducer from './reducers';
import { composeWithDevTools } from 'redux-devtools-extension';
const store = createStore(
rootReducer,
composeWithDevTools(
applyMiddleware(debounceMiddleware)
// ...add other middlewares here
)
);
export default store;
Sets up the Redux store and applies the debounceMiddleware created earlier.
/* Your HTML */
<!DOCTYPE html>
<html lang='en'>
<head>
<meta charset='UTF-8'>
<title>Debounced Input Example</title>
<script src='/path_to_your_compiled_js_bundle.js' defer></script>
</head>
<body>
<div id='app'></div>
</body>
</html>
The HTML markup with a script tag to include the compiled JavaScript bundle where the React component and Redux store are defined.
/* Your CSS */
input {
padding: 10px;
margin: 10px;
border: 1px solid #ccc;
border-radius: 4px;
}
Basic CSS for styling the input element.