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

Dispatch an action on animation end? #32

Open
staff0rd opened this issue Feb 24, 2021 · 1 comment
Open

Dispatch an action on animation end? #32

staff0rd opened this issue Feb 24, 2021 · 1 comment

Comments

@staff0rd
Copy link

Looking to dispatch an arbitrary action (once) on animation/sequence end. I tried hax Animate at the end of a Sequential with something like:

Animate({
  path: "/whatever",
  state: 1,
  duration: 1,
  tick: () => {
    dispatch(someAction());
    return 1;
  },
}),

But this throws

Error: You may not call store.getState() while the reducer is executing. The reducer has already received the state as an argument. Pass it down from the top reducer instead of reading it from the store.

Also used Become to set some property to values like Not Animating, Animating and Complete and used middleware to intercept TICK, check for Complete and dispatch Not Animating, but the property is Complete at multiple intercepts before the dispatch finishes.

Any pointers on how I might dispatch a single action at animation end?

@pirate
Copy link
Member

pirate commented Feb 24, 2021

An important foundational principle of this library is that you are not allowed to dispatch actions from the animation system, the state flows unidirectionally from your UI controller -> actions -> animations. We found that allowing animations to re-dispatch actions later on only causes pain, as it leads to inscrutable circular dependencies / side effects that are hard to track down.

This is because the library is based on the idea of laying all your animations out declaratively on a flat timeline, and then you can scrub forward and backward through that timeline once it's been defined. Crucially, you are not allowed to modify that timeline as a side effect of scrubbing through it, otherwise it would break the ability to do deterministic scrubbing.

The solution is to dispatch both your animation, and the 2nd action from the same initial place, e.g.

function onClick() {
    dispatch(Animate({..., end_time: Date.now() + 1000}))
    setTimeout(() => {dispatch({some other action})}, 1000)
}

You could also do this with redux-thunk or another side-effect-handling redux library instead of setTimeout.

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

2 participants