Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Debounce/delay storage of state in history #24

Closed
subblue opened this issue Jan 4, 2016 · 10 comments
Closed

Debounce/delay storage of state in history #24

subblue opened this issue Jan 4, 2016 · 10 comments

Comments

@subblue
Copy link

subblue commented Jan 4, 2016

I'm interested to use redux-undo to replace an ad-hoc undo implementation I currently have in my app. One thing I'm wondering about is being able to delay/debounce the storage of the app state for situations where a text input or slider might be changing and there will be a stream of rapid state changes.

I currently use a simple clearTimeout & setTimeout of 1000ms after which the state is stored in the history object. Then each undo action gives a sensible undo change (rather than having to step back through tens of tiny changes of a slider value or every character of a word typed into an input box).

I'm wondering how a similar thing could be achieved using redux-undo?

Thanks!

@omnidan
Copy link
Owner

omnidan commented Jan 4, 2016

Yes, that's totally possible with an action filter. You can keep using your current system, too (I haven't tried the code, though):

let filter
undoable(reducer, function filterActions(action, currentState, previousState) {
  if (!filter) {
    filter = setTimeout(() => { filter = false }, 1000)
    return true
  }
  return false
})

I hope this helped you, if you have any further questions don't hesitate to ask 😄

@subblue
Copy link
Author

subblue commented Jan 4, 2016

Thanks for your answer, but I don't think this is quite what I'm aiming for.

Your action filter will prevent the state being added to the history for a period of time, but after the timeout there is nothing to trigger the history to be updated with the new state (unless there is something else happening behind the scenes?)

Imagine an input box that triggers a state change on every keypress. I don't want to store a new history entry for every individual key event, but only after there hasn't been a keypress for at least 1000 ms. Only then the present state should be saved in the history.

I suppose alternatively I could somehow update just the present attribute of the history object if the update occurs within a threshold time (rather than shifting it onto the past array), but that doesn't seem particularly tidy.

@omnidan
Copy link
Owner

omnidan commented Jan 4, 2016

@subblue Ah, I get you now. I think the better way to do this is doing it in the component. That way you can make sure it only sends/dispatches the event if there hasn't been another keypress for at least X ms.

@omnidan
Copy link
Owner

omnidan commented Jan 12, 2016

@subblue Have you solved this issue yet? 😄

@subblue
Copy link
Author

subblue commented Jan 12, 2016

In the end I rolled my own implementation which is a mix of this lib and the example given in the Redux docs as I needed a couple of other special bits.
My implementation keeps track of the last update time, and if there is another update within the time threshold it just replaces the last state rather than appending a new one. This stops the undo history growing for every little quick change.

@subblue subblue closed this as completed Jan 12, 2016
@omnidan
Copy link
Owner

omnidan commented Jan 12, 2016

Sounds good, glad you figured it out 👌 - would be a good case for a higher-order reducer (if it isn't already one).

@lostfictions
Copy link

Hey @subblue, do you happen to have your custom implementation viewable anywhere? I'm facing this same problem. I was thinking I might be able to get what I need by duct-taping this, redux-batched-subscribe, and lodash's debounce together somehow, but it's tricky enough that I'd rather not solve it from scratch if I don't need to.

@lostfictions
Copy link

(In particular, it's not totally clear to me from the redux-undo docs whether there's any way to cleanly update the present state without pushing anything new to the undo history. Without that, it seems like it'd be a lot more difficult to handle all sorts of little edge cases around debouncing...)

@omnidan
Copy link
Owner

omnidan commented Feb 22, 2016

@lostfictions if an action is filtered by a filter function, it still changes present, but doesn't update the history: https://github.com/omnidan/redux-undo/blob/master/src/index.js#L239 - hope I could help you a bit :)

@lostfictions
Copy link

Ah, thanks! I'll try and make this work then :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants