Open amasad opened 8 years ago
That's an interesting problem, and not one I've had to tackle yet personally. I think one option would be to always make your transaction ID something like the ID of the thing you are updating, then always fire a REVERT
action before firing your begin transaction action. e.g.
import {BEGIN, COMMIT, REVERT} from 'redux-optimist';
import request from 'then-request';
const inProgress = {};
export default function (store) {
return next => action => {
if (action.type !== 'SET_VALUE') {
return next(action);
}
const key = action.key;
if (key in inProgress) {
clearTimeout(inProgress[key]);
next({
type: 'PREPARE_DEBOUNCED_SET',
optimist: {type: REVERT, id: key}
});
}
next({
...action,
optimist: {type: BEGIN, id: key}
});
inProgress[key] = setTimeout(() => {
delete inProgress[key];
request('POST', '/add_todo', {text: action.text}).getBody().done(
res => next({
...action,
type: 'SET_VALUE_COMPLETE',
response: res,
optimist: {type: COMMIT, id: key}
}),
err => next({
...action,
type: 'SET_VALUE_FAILED',
error: err,
optimist: {type: REVERT, id: key}
})
);
}, 1000);
};
};
I haven't tested that, so I don't know for sure whether it works properly. It occurs to me that maybe we shouldn't have a special BEGIN
type, and should just automatically BEGIN
when you fire the first action with a given transactionID. That would allow you to remove the bit where you fire an action to revert the in-progress transaction.
Very briefly tried to implement this and it proved a bit tricky. I ended up keeping component local state and then debouncing the action dispatch at the component level. I may come back to this in the future though since it's nice to not have local state.
What's the best way to debounce server requests? I have an editable text area that I want to do auto save on. The textareas' value is handled by redux but I don't want to overwhelm the server with updates on every keystroke. Any ideas?