Reputation: 8946
I am migrating over from Redux to Redux Toolkit. The simplified code I have here is for debounced update using lodash/debounce.
import debounce from "lodash/debounce";
const updateApplication = async (app, dispatch) => {
const state = getState();
try {
const result = await update(app);
dispatch({
type: UPDATE,
result: result
});
} catch (err) {
console.log(err);
}
};
export default debounce(updateThunk, 2000);
The problem is when I move over to createAsyncThunk it does not get executed.
const updateApp = createAction("app/update");
const updateApplication = createAsyncThunk(
"app/updateDebounced",
async (app, { dispatch }) => {
try {
const result = await update(app);
dispatch(updateApp(result))
);
}
} catch (err) {
// console.log(err);
}
}
);
export default debounce(updateApplication, 2000)
How do I make it work?
Upvotes: 6
Views: 5288
Reputation: 6589
const updateApp = createAction("app/update");
const handler = async (app, { dispatch }) => {
try {
const result = await update(app);
dispatch(updateApp(result));
} catch (err) {
// console.log(err);
}
}
const debouncedHandler = debounce(handler, 2000);
export default createAsyncThunk(
"app/updateDebounced",
debouncedHandler
);
Upvotes: 8
Reputation: 359
Here is how I am doing it with typescript and lodash to make a debounced call to an api
import { createAsyncThunk, AsyncThunkPayloadCreator } from '@reduxjs/toolkit';
import { debounce } from 'lodash';
// Interface for my api call
interface UpdateParams {
object_id: number;
input_field_a: string;
input_field_b: string;
}
// Handler method for asyncThunk
const updateHandler: AsyncThunkPayloadCreator<any, UpdateParams, {}> = async (params: UpdateParams, { rejectWithValue }) => {
const { object_id, ...values } = params;
const response = await window.api.put(`api/object/${object_id}`, values);
return response && response.data ? response.data : rejectWithValue('Failed to update object');
}
// Create debounced handler with timer of 1 second
const debouncedHandler = debounce(updateHandler, 1000);
// AsyncThunk method
const updateObject = createAsyncThunk(
'update/object',
debouncedHandler
);
Upvotes: 0
Reputation: 1
A debounced analogue of createAsyncThunk
from @reduxjs/toolkit
import { createAsyncThunk } from '@reduxjs/toolkit';
/**
* A debounced analogue of the `createAsyncThunk` from `@reduxjs/toolkit`
* @param {string} typePrefix - a string action type value
* @param payloadCreator - a callback function that should return a promise containing the result
* of some asynchronous logic
* @param {number} wait - the number of milliseconds to delay.
* @param {Object} [options] - the options object
* @param {number} [options.maxWait = 0] - The maximum time `payloadCreator` is allowed to be
* delayed before it's invoked.
* @param {boolean} [options.leading = false] - Specify invoking on the leading edge of the timeout.
*/
const createDebouncedAsyncThunk = (typePrefix, payloadCreator, wait, options) => {
const { maxWait = 0, leading = false } = options ?? {};
let timer = 0;
let maxTimer = 0;
let resolve;
const invoke = () => {
clearTimeout(maxTimer);
maxTimer = 0;
if (resolve) {
resolve(true);
resolve = undefined;
}
};
const cancel = () => {
if (resolve) {
resolve(false);
resolve = undefined;
}
};
return createAsyncThunk(typePrefix, payloadCreator, {
condition() {
const immediate = leading && !timer;
clearTimeout(timer);
timer = setTimeout(() => {
invoke();
timer = 0;
}, wait);
if (immediate) return true;
cancel();
if (maxWait && !maxTimer) maxTimer = setTimeout(invoke, maxWait);
return new Promise(res => {
resolve = res;
});
},
});
};
export default createDebouncedAsyncThunk;
Upvotes: 0